-
Notifications
You must be signed in to change notification settings - Fork 293
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Imprinting and matching #1353
Imprinting and matching #1353
Conversation
adam-urbanczyk
commented
Jun 20, 2023
•
edited
Loading
edited
- Extract nested iterator
- Add tests
- Refactor toVTK to use the new iterator
- toVTK rendering improvements -> split into triangles with normals and edges/points without
- Refactor other methods to use the new iterator
@shimwell this PR still needs some polishing, but I think that the functionality is there. Could you verify that this is what you want: b1 = cq.Workplane().box(1, 1, 1)
b2 = cq.Workplane(origin=(1,0,0)).box(1,1,1)
assy = cq.Assembly().add(b1, color=cq.Color("red")).add(b2)
r, o = cq.occ_impl.assembly.imprint(assy) where s1,s2 = r.Solids()
assert(s1 in o)
assert(s2 in o) and last, but not least: assert(len(r.Faces())== 11) |
That does look ideal from your description above and the code above. I shall try to install this branch and run some models to see how it behaves with curves, faces that are partially shared, faces share between more that two volumes and anything else I can think of. Many thanks for all of this targeted development |
Ok I think I understand how to correlate the original assembly objects to the imprinted solids. I adapted the code to print out:
I notice the assembly has 3 objects so guess the first one is the assembly structure itself. I wonder if that is always present. But i can see matching numbers in the original, imprinted and the correspondence dict which is just what I needed. Note to self the ID appears to be made from the assembly ID and the solid ID. Perphaps use import cadquery as cq
b1 = cq.Workplane().box(1, 1, 1)
b2 = cq.Workplane(origin=(1,0,0)).box(1,1,1)
assy = cq.Assembly().add(b1, color=cq.Color("red")).add(b2)
r, o = cq.occ_impl.assembly.imprint(assy)
print('imprinted solids', r.Solids, '\n')
for k, v in o.items():
print('imprinted solid', k, 'corresponding original solid id', v)
print('\noriginal solds ID', assy.objects.keys()) pint out imprinted solids <bound method Shape.Solids of <cadquery.occ_impl.shapes.Shape object at 0x7f53abcc17f0>>
imprinted solid <cadquery.occ_impl.shapes.Solid object at 0x7f53abcc15b0> corresponding original solid id ('9910a432-0fb2-11ee-a766-a434d95c2a9c/9910a5e0-0fb2-11ee-a766-a434d95c2a9c',)
imprinted solid <cadquery.occ_impl.shapes.Solid object at 0x7f53abcc1640> corresponding original solid id ('9910a432-0fb2-11ee-a766-a434d95c2a9c/9910a6a8-0fb2-11ee-a766-a434d95c2a9c',)
original solds ID dict_keys(['9910a432-0fb2-11ee-a766-a434d95c2a9c', '9910a5e0-0fb2-11ee-a766-a434d95c2a9c', '9910a6a8-0fb2-11ee-a766-a434d95c2a9c']) So in this case the first original solid is the first imprinted solid |
Yes the top level assy is empty - it has no Shape object. In general it does not have to be like that. |
I've ran a few tests on odd shapes and checked the number of faces is correct and this works in the cases I tried. The unique ID dictionaries also work nicely. I've been trying to pass the resulting imprinted assembly into gmsh by trying the import cadquery as cq
small = cq.Workplane().box(1, 1, 1)
big = cq.Workplane(origin=(1,0,0)).box(1,2,2)
assy = cq.Assembly()
assy.add(small)
assy.add(big)
r, o = cq.occ_impl.assembly.imprint(assy)
print(len(r.Faces())) # prints 12 which is correct
topods = r.wrapped # perhaps this is not the best way to get a topoDS
object_to_pass_to_gmsh=topods._address() error message
|
I think you need to install |
Codecov Report
@@ Coverage Diff @@
## master #1353 +/- ##
==========================================
- Coverage 94.16% 94.14% -0.02%
==========================================
Files 26 26
Lines 5584 5601 +17
Branches 954 952 -2
==========================================
+ Hits 5258 5273 +15
- Misses 194 195 +1
- Partials 132 133 +1
📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
@shimwell did you manage? FYI: I think we'll switch to 7.7.1 after releasing CQ 2.3, but that should not stop you form using it in a local dev env. |
I have been trying but struggling to get the environment to include everything (ocp7.7.1, gmsh, cadquery imprint branch). I've been trying to conda install from the ocp dev tar.gz, pip install from the cadquery branch and conda install gmsh from conda forge but keep getting package conflicts. I was able to test a bunch of shapes with share surfaces end up with the right number of surfaces so I think this PR does what it aims to do. As for the gmsh integration I think that get easier to test with releases |
Hm, env.yaml does not seem to support labels. |
Trying that environment.yml you with a
Then running this script import cadquery as cq
import gmsh
small = cq.Workplane().box(1, 1, 1)
big = cq.Workplane(origin=(1,0,0)).box(1,2,2)
assy = cq.Assembly()
assy.add(small)
assy.add(big)
r, o = cq.occ_impl.assembly.imprint(assy)
print(len(r.Faces())) # prints 12 which is correct
topods = r.wrapped
object_to_pass_to_gmsh=topods._address()
gmsh.initialize()
gmsh.option.setNumber("General.Terminal", 1)
volumes = gmsh.model.occ.importShapesNativePointer(object_to_pass_to_gmsh)
gmsh.model.occ.synchronize()
gmsh.option.setNumber("Mesh.Algorithm", 1)
gmsh.option.setNumber("Mesh.MeshSizeMin", 20)
gmsh.option.setNumber("Mesh.MeshSizeMax", 30)
gmsh.model.mesh.generate(2)
gmsh.write("gmsh_of_cadquery_in_memory.msh") Get me to this new (for me) error when importing gmsh.
|
Looks like you are using gmsh that was not built against 7.7.1 but does not pin the occt version fully. You could try installing the latest version/build of gmsh, but I'd propose to keep this discussion outside of this PR. You can still test with saving to disk, the order of solids should be stable after export/import. Keys of the output dict are added in that order too. |
Let me know what you think @lorenzncode @jmwright . |
from the example at the top I am just wondering why the values of the r, o = cq.occ_impl.assembly.imprint(assy)
all_values = list(o.values())
type(all_values[0])
>>> <class 'tuple'>
len(all_values[0])
>>> 1 |
My understanding is because there can be more than one origin per solid in the result. b1 = cq.Workplane().box(1, 1, 1)
b2 = cq.Workplane(origin=(-0.2,0,0)).box(1,1,1) |
@adam-urbanczyk I tested the refactor against the KiCAD generator and the files seem unchanged, so that's good. The rest of the code looks good to me, but I see that changes are still being pushed to this PR. |
There is a line in the environment.yml file that says Do we need to change this to I guess |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@adam-urbanczyk This still seems to work fine with the KiCAD generator.
Alright, I'll merge tomorrow. @shimwell any last thoughts? |
No further thoughts from me, I've tested this with the workflow I'm hoping to use it in and am getting good results. All good from my point of view |
Just to mention I've been using object_to_pass_to_gmsh=topods._address()
gmsh.initialize()
gmsh.option.setNumber("General.Terminal", 1)
volumes = gmsh.model.occ.importShapesNativePointer(object_to_pass_to_gmsh)
|