I personally use OpenSCAD. It's a different approach of course, it's not point-and-click. It generates STL so good for 3D printing.
'Vanilla' OpenSCAD is not the easiest to fully get to grips with, as its *your* responsibility to avoid generating non-manifold meshes, by extending 2nd (and subsequent) children of difference() operations so they extend past the surface of the first child, and by overlapping the children of union() (and implied union) operations, and its difficult to do so unless you fully embrace parameterizing all dimensions of your models so you can 'do the math' and have it calculate the required sizes, rotates and translates at render time.
Also, its too easy to get into the mindset of doing everything by unioning and differencing its 3D primitive objects, which rapidly gets out of hand when you start wanting stuff like radiused edges. It is often preferable to calculate a list of points for a polygon with the required curves then extrude that, either making the required 3D shape directly, or use it as a difference tool to 'punch out' the features you want.
The biggest conceptual hurdle to those used to procedural languages is that OpenSCAD is a declarative language, thus any variable can only have a single value for its entire scope (although it can be overridden with a new value in an inner scope). i.e. you cannot do
a=a+1; which obviously limits the use of iterative algorithms, unless implemented by recursion.
Another issue is broken or out-of-date OpenGL drivers on your PC may cause problems with OpenSCAD Preview, resulting in either no visible object or in preview artifacts. It all 'comes good' when you actually render the object as that doesn't call on the graphics driver to perform 3D Boolean operations. As a workaround you can use transparency and the 'Thrown Together' view to get a feel for child object positioning before committing to a render.
I had good hopes for openSCAD but was disappointed while learning it by it's lack of NURBs surfaces and that it can only export polygonal models. Still, depending on what you need it could be good too.
Its not NURBs but OpenSCAD can do arbitrary computed surfaces. In 'vanilla' OpenSCAD, that's limited to importing
heightmap surfaces from an external file, but
The Belfry OpenScad Library, v2 (BOSL2) adds the capability to generate a surface from an array or an arbitrary function
[ref]. You can also generate Bezier surfaces from an array of control points
[ref].
BOSL2 also simplifies combining 3D objects while avoiding generating non-manifold meshes as you can simply attach them with a defined overlap, removing the need to carefully and explicitly calculate all the translations and rotations required to do so
[ref].