Name of a solid in a compound - from selection

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
User avatar
DeepSOIC
Veteran
Posts: 7896
Joined: Fri Aug 29, 2014 12:45 am
Location: used to be Saint-Petersburg, Russia

Re: Name of a solid in a compound - from selection

Post by DeepSOIC »

bernd wrote:because the inner could have less volume than the outer
True :oops: . Bounding box diagonal is used in wire sorting for face making, so it should work for solids too.
HoWil
Veteran
Posts: 1279
Joined: Sun Jun 14, 2015 7:31 pm
Location: Austria

Re: Name of a solid in a compound - from selection

Post by HoWil »

bernd wrote: Just realized the system might not work if a solid is inside another solid, because all elements of the inner solid belong to the outer solid too. I need to try this on the mesh region object.
You maybe consider another test case like a sphere completely inside a box where one not so easily can select a face or edge. This shortcoming was the starting point to write the Element-selector macro.

Here an according file where I would like to select the inner solid as part of the BooleanFragments:

BR,
HoWil
HoWil
Veteran
Posts: 1279
Joined: Sun Jun 14, 2015 7:31 pm
Location: Austria

Re: Name of a solid in a compound - from selection

Post by HoWil »

Hi,
Let me post some code snippet /example here. It is more for documentation.

The example builds a BooleanFragments-compsolid and prints all elements found with a selection in the middle of the screen.

Code: Select all

# -*- coding: utf-8 -*-
"""
Created on Mon Apr 17 20:02:45 2017

@author: HoWil
"""
##%% This cell is only needed if the code is executed in an external environment like spyder
#
##%gui qt   #  not needed in Spyder3, qt5??
#
#import sys
#sys.path.append("/usr/lib/freecad-daily/lib")
#
#import FreeCADGui
#FreeCADGui.showMainWindow()


#%%###################################################
# Creation of a FC document and a BooleanFragments CompSolid
# parts from Bernds example from https://forum.freecadweb.org/viewtopic.php?f=10&t=18937

from FreeCAD import *

App.newDocument("Unnamed")
App.setActiveDocument("Unnamed")
App.ActiveDocument = App.getDocument("Unnamed")
Gui.ActiveDocument = Gui.getDocument("Unnamed")

doc = App.ActiveDocument

# build a CompSolid out of a box and a inner sphere
import Part
sphere_obj1 = doc.addObject('Part::Sphere', 'Sphere1')
FreeCAD.ActiveDocument.getObject("Sphere1").Radius = '2 mm'
box_obj2 = doc.addObject('Part::Box', 'Box2')
box_obj2.Placement.Base = (-5, -5, -5)
import BOPTools.SplitFeatures
cs = BOPTools.SplitFeatures.makeBooleanFragments(name= 'CompSolid')
cs.Objects = [sphere_obj1, box_obj2]
cs.Mode = "CompSolid"
for obj in cs.ViewObject.Proxy.claimChildren():
    obj.ViewObject.hide()

doc.recompute()
Gui.SendMsgToActiveView("ViewFit")

#%%###################################################
# get the size of the active view for later selecting at the mid-point of the screen
av = FreeCADGui.activeView()
size_av = av.getSize()     # get size of the 3D screen

#%%################################################################################
#pos = (0, 0) # alternative selection position at the lower left corner of the 3d view
pos = (size_av[0]/2, size_av[1]/2) # position at the center of the 3D view


# get all elements beneath a point in the 3d-view (screen) plan
element_list = FreeCADGui.ActiveDocument.ActiveView.getObjectsInfo((int(pos[0]), int(pos[1])))

import FemMeshTools

print('######################\n')
print(' The following elements were found in the compsolid\n')

for e in element_list:

    label_object = str(e["Object"])
    label_component = str(e["Component"])

    el_to_look_for = label_component
    compsolid = App.ActiveDocument.getObjectsByLabel(label_object)[0]
    found_solid_cont_el = []
    found_solid_names_cont_el = []

    if type(compsolid.Shape) == Part.Compound:
        ele_shape = FemMeshTools.get_element(compsolid, el_to_look_for)   # the method getElement(element) does not return Solid elements
        for s in compsolid.Shape.Solids:
            if type(ele_shape) is Part.Face:
                for f in s.Faces:
                    if f.isSame(ele_shape):
                        found_solid_cont_el.append(s)
            if type(ele_shape) is Part.Edge:
                for e in s.Edges:
                    if e.isSame(ele_shape):
                        found_solid_cont_el.append(s)
            if type(ele_shape) is Part.Vertex:
                for v in s.Vertexes:
                    if v.isSame(ele_shape):
                        found_solid_cont_el.append(s)

    # compare all found solids with artificial names created as 'SolidX' wher X is an integer
    for sf in found_solid_cont_el:
        for n, s in enumerate(compsolid.Shape.Solids):
            if sf.isSame(s):
                found_solid_names_cont_el.append('Solid'+str(n+1))
                #FIXME: FreeCADGui.Selection.addSelection(FreeCAD.ActiveDocument.getObject(sf))
                #TODO: Last question how to highlight the found sub-solid!!!!!!!! and its faces!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    print('######################\n')
    print(el_to_look_for)
    print(found_solid_names_cont_el)
The output is as follows. I do not understand why e.g. 'Face6' is found twice? :

Code: Select all

######################

Face4
['Solid2']
######################

Face4
['Solid2']
######################

Edge1
['Solid1', 'Solid2']
######################

Face1
['Solid1', 'Solid2']
######################

Edge2
['Solid1', 'Solid2']
######################

Vertex1
['Solid1', 'Solid2']
######################

Face1
['Solid1', 'Solid2']
######################

Edge2
['Solid1', 'Solid2']
######################

Edge3
['Solid1', 'Solid2']
######################

Vertex2
['Solid1', 'Solid2']
######################

Face6
['Solid2']
######################

Face6
['Solid2']
What I would need now is a method to highlight the solids inside the BooleanFragments ('Solid1', 'Solid2').
If I simply add it to the selection with

Code: Select all

FreeCADGui.Selection.addSelection(FreeCAD.ActiveDocument.getObject(sf))
the complete Compsolid is selected/highlighted.

BR,
HoWil
User avatar
Chris_G
Veteran
Posts: 2579
Joined: Tue Dec 31, 2013 4:10 pm
Location: France
Contact:

Re: Name of a solid in a compound - from selection

Post by Chris_G »

Hi,
If I simply add it to the selection with

Code: Select all

FreeCADGui.Selection.addSelection(FreeCAD.ActiveDocument.getObject(sf))
the complete Compsolid is selected/highlighted.
Because your code adds a whole object to selection.
You can add subshapes to selection :

Code: Select all

Gui.Selection.addSelection(obj,'Face2')
HoWil
Veteran
Posts: 1279
Joined: Sun Jun 14, 2015 7:31 pm
Location: Austria

Re: Name of a solid in a compound - from selection

Post by HoWil »

Dear Chris_G,
Thanks for your reply.
Chris_G wrote:Because your code adds a whole object to selection.
In my code sf is a sub-solid like 'Solid1' or 'Solid2' of my CompSolid called 'compsolid'. I do not hand over the complete CompSolid but the complete CompSolid is highlighted.
Chris_G wrote:You can add subshapes to selection :
If you try

Code: Select all

Gui.Selection.addSelection(compsolid ,'Solid1')
after running my above posted code you will see that the both domains of the CompSolid are selected although 'Solid1' is the inner, spherical domain.
BR,
HoWil
User avatar
Chris_G
Veteran
Posts: 2579
Joined: Tue Dec 31, 2013 4:10 pm
Location: France
Contact:

Re: Name of a solid in a compound - from selection

Post by Chris_G »

It looks like there is something buggy here :

Code: Select all

# obj is the compsolid
Gui.Selection.addSelection(obj,'Solid2')
s=Gui.Selection.getSelectionEx()
s
# result : [<SelectionObject>]

s0= s[0]
s0.HasSubObjects
# result : True

s0.SubObjects
# result :
Traceback (most recent call last):
  File "<input>", line 1, in <module>
Base.FreeCADError: Unknown exception while reading attribute 'SubObjects' of object 'SelectionObject'
HoWil
Veteran
Posts: 1279
Joined: Sun Jun 14, 2015 7:31 pm
Location: Austria

Re: Name of a solid in a compound - from selection

Post by HoWil »

Chris_G wrote:It looks like there is something buggy here
Should I file a bug report?
Br Howil
User avatar
Chris_G
Veteran
Posts: 2579
Joined: Tue Dec 31, 2013 4:10 pm
Location: France
Contact:

Re: Name of a solid in a compound - from selection

Post by Chris_G »

I don't know ...
I'll let the main developers answer to that.
In FreeCAD Selection tool, I have only seen subObjects of type ('Vertex','Edge','Face') (i.e shapes that can be picked in the 3D view)
So, maybe the selection tool is simply not meant to be used with the other OCC topoShapes ( wires, shells, solids, compounds ) ?
Post Reply