Duplicating rhino breps in python

Edit: This question is based on a mistake and the assumptions in it abut which methods work are not true. Duplicate() does work for breps. DuplicateGeometry() works specifically for docobjects. Python copy not working might be a bug.

I am trying to perform the seemingly simple task of copying a brep using Rhino.Geometry in python so I can perform a simple mirror transform and union. I managed to do it by deconstructing the brep into individual surfaces, duplicating them and using them to make a new brep. The new brep for some reason did not work with a boolean union, though, despite it working fine if I output it to grasshopper and performed the union there. No idea about the second part, but duplicating a brep in python is hard, I do not know about other objects.

Methods I have tried:
Duplicate() - does not actually duplicate the object, transformations to the new object apply to the original.
DuplicateBrep() - same
DuplicateGeometry() - Brep object has no attribute DuplicateGeometry
python copy() and deepcopy() - do not work because the brep object cannot be pickled

Would rather not touch rhinoscriptsyntax and its indirect way of referencing objects, but if I have to, I will.

See here how to duplicate geometry ( rhino-developer-samples/rhinocommon/cs/SampleCsCommands/SampleCsDuplicateObjectFromNameTag.cs at 4a3f456684808310c58ed61c93fb5ccae85ac71e · mcneel/rhino-developer-samples · GitHub ), then duplicate the attributes ( rhino-developer-samples/rhinocommon/cs/SampleCsCommands/SampleCsDuplicateObjectFromNameTag.cs at 4a3f456684808310c58ed61c93fb5ccae85ac71e · mcneel/rhino-developer-samples · GitHub ) and finally add a new object with the duplicated data ( rhino-developer-samples/rhinocommon/cs/SampleCsCommands/SampleCsDuplicateObjectFromNameTag.cs at 4a3f456684808310c58ed61c93fb5ccae85ac71e · mcneel/rhino-developer-samples · GitHub ).

It will work the same way in Python.

Once you have your duplicate use it to apply transform, then select both original and transformed duplicate and perform your union.

1 Like

That is not correct - Duplicate() does indeed create a full deep copy

If you run this code:

#! python 3
import scriptcontext as sc
import Rhino

plane=Rhino.Geometry.Plane.WorldXY
sph=Rhino.Geometry.Sphere(plane,10)
sph_brep=sph.ToBrep()
dup_sph_brep=sph_brep.Duplicate()
xform=Rhino.Geometry.Transform.Scale(plane,2,2,2)
sph_brep.Transform(xform)
sc.doc.Objects.AddBrep(sph_brep)
sc.doc.Objects.AddBrep(dup_sph_brep)
sc.doc.Views.Redraw()

The original will transform but not the copy. In the file you will find two different sized spheres.
If you run the following:

#! python 3
import scriptcontext as sc
import Rhino

plane=Rhino.Geometry.Plane.WorldXY
sph=Rhino.Geometry.Sphere(plane,10)
sph_brep=sph.ToBrep()
dup_sph_brep=sph_brep.Duplicate()
xform=Rhino.Geometry.Transform.Scale(plane,2,2,2)
dup_sph_brep.Transform(xform)
sc.doc.Objects.AddBrep(sph_brep)
sc.doc.Objects.AddBrep(dup_sph_brep)
sc.doc.Views.Redraw()

the duplicate will transform but not the original.

This seems to be a particular problem with Python3 - it works in IronPython2 - I have also run into this.

1 Like

Thank you, this is true. My mistake came from the boolean union returning wrong results, deleting the original half instead of creating a union. I am still figuring this out.

Thank you, I did not realize that a docobject is a particular type of object and was convinced that DuplicateGeometry did not work as intended.

By the way, what was causing the issue with boolean union is that the mirroring flipped the brep normals. I have not tested it much, but this seems to happen as a rule. Is this how it is supposed to work?