TAGGED: geometry, scripting, spaceclaim
-
-
June 12, 2023 at 1:08 pmramiromenaSubscriber
Dear Ansys Learning Forum Community,
I am trying to select a specific face in a geometry. The easiest way to do this task is by knowing in advance the index of the face of interest. However, this option lacks of scalability if my geometry is modified or generated in a different order. This solution is referred as Option 1.
So, other option is to use the FilterByArea method. This works fine as long as your faces have a unique area, otherwise, you will select multiple faces instead of only one. This solution is referred as Option 2.
Then, by searching the available options, there is the FilterByBoundingBox method where you can select a face that intersects with a previously defined box. This method looks as the most generic so that you can control the way a face is selected. However, due to the lack of documentation in SpaceClaim or the absence of a similar example, I am not able to use this method properly. Maybe is due to an error in the syntax or in my understanding of the method. Please, could you help me? This solution is referred as Option 3.
Attached you will find a minimal working example (MWE) with the implementation of Option 1, 2 and 3. This last one is currently not working as is the one I am interested the most. Feel free to add/modify its content.
However, if you know a better solution to select a specific face (i.e based on its normal or another feature, feel free to share your valuable know-how)
As always, thank you for your help.
Best regards,
Ramiro
#####
"""
Minimal Working Example MWE
Author: Ramiro MENA ANDRADE
Date: 2023-06-12
Script to generate a Cube of dimensions Cube_X, Cube_Y and Cube_Z
and select faces based on three different methods:
- Option1: When the index of the face is known in advance (not useful to fully automatize a code)
- Option2: By using FilterByArea method (not useful if more than one face has the same area)
- Option3: By using FilterByBoundingBox method (could be useful, but I do not know how to write the proper syntax)
"""
# Python Script, API Version = V19
#*************************************
# Part 1: Geometry definition (dimensions in mm)
#*************************************
Cube_X= 10
Cube_Y= 20
Cube_Z= 5
pointA = [0,0]
pointB = [Cube_X,0]
pointC = [Cube_X,Cube_Y]
tol = 0.01 #define a tolerance
area = Cube_X*Cube_Y #calculate the area
#%%
#*********************************
#Part2: Geometry generation
#*********************************
sectionPlane = Plane.PlaneXY
result = ViewHelper.SetSketchPlane(sectionPlane, None)
# EndBlock
# Set New Sketch
result = SketchHelper.StartConstraintSketching()
# EndBlock
# Sketch Rectangle
point1 = Point2D.Create(MM(pointA[0]),MM(pointA[1]))
point2 = Point2D.Create(MM(pointB[0]),MM(pointB[1]))
point3 = Point2D.Create(MM(pointC[0]),MM(pointC[1]))
result = SketchRectangle.Create(point1, point2, point3)
# Solidify Sketch
mode = InteractionMode.Solid
result = ViewHelper.SetViewMode(mode, None)
# EndBlock
# Extrude 1 Face
selection = FaceSelection.Create(GetRootPart().Bodies[0].Faces[:])
options = ExtrudeFaceOptions()
options.ExtrudeType = ExtrudeType.Add
result = ExtrudeFaces.Execute(selection, MM(Cube_Z), options)
# EndBlock
#%%
#************************************************
#Part 3: Selection of faces by different methods
#*************************************************
# OPTION 1: Create Named Selection Group (Top)
# PROBLEM: YOU NEED TO KNOW IN ADVANCE THE INDEX OF THE FACE
primarySelection = FaceSelection.Create(GetRootPart().Bodies[0].Faces[0])
secondarySelection = Selection.Empty()
result = NamedSelection.Create(primarySelection, secondarySelection)
result = NamedSelection.Rename("Group1", "Option1")
# EndBlock
#OPTION 2: Create a named selection by using FilterByArea
#PROBLEM: FOR THIS CASE, MULTIPLE FACES CAN HAVE THE SAME AREA, SO YOU CAN NOT SELECT A SPECIFIC FACE
comp = Selection.Create(GetRootPart())
faces = comp.ConvertToFaces().FilterByArea(MM2(area-tol),MM2(area+tol))
faces.CreateAGroup('Option2')
#OPTION 3: Create a named selection by using FilterByBoundingBox Method
#PROBLEM: I DO NOT KNOW THE PROPER SYNTAX FOR USING THIS METHOD CORRECTLY
#Create Points
min_point = Point.Create(MM(pointA[0]), MM(pointA[1]), MM(0))
max_point = Point.Create(MM(pointC[0]), MM(pointC[1]), MM(0))
#Create a Box
mbox = Box.Create(min_point, max_point)
#Apply the Filter to a face (fface means filtered face)
fface = comp.ConvertToFaces().FilterByBoundingBox(mbox)
fface.CreateAGroup('Option3') -
June 14, 2023 at 11:49 amAniketForum Moderator
Hi Ramiro,
First of all very well-written question! Kudos for that! There was an issue in older APIs of FilterByBoundingBox which is fixed in 2023 R1.
so something, as follows, would work in 2023R1:
from SpaceClaim.Api.V23 import *
PartSel = Selection.Create(GetRootPart())
faces = PartSel.ConvertToFaces()
BoundingBox = Box.Create(MM(-30),MM(-30),MM(-30),MM(30),MM(30),MM(30))
facesInBoundingBox = faces.FilterByBoundingBox(BoundingBox)You may want to upgrade to 2023R1.
If that's not possible, possibly you can loop through faces and check their centroid such as:
GetRootPart().Bodies[0].Faces[0].EvalMid().Point
-Aniket
-
June 14, 2023 at 12:24 pmramiromenaSubscriber
Hi Aniket.
Thank you for your positive feedback and for your quick reply. Currently I do not have the 2023R1 version, but I am glad to know that there is a solution in the future version. In the meantime, the hint of using the centroid is super useful.
I will proceed to update my script and kudos for you too :).
Cheers,
Ramiro
-
September 27, 2023 at 12:41 pmchristian.schefflerSubscriber
Hi Aniket,
are you sure the bug in the FilterByBoundingBox() and FilterByBoundingSphere() method is already fixed in V23 version (ANSYS 2023 R1)?
Could anybody test it?My experience with V23: Neither of these functions is working in my script :(
It seems that it does not create a subset of the total set, although I thoroughly checked the parameters.Cheers,
Christian-
September 27, 2023 at 5:09 pmAniketForum Moderator
That wont work as is but following seems to working:
PartSel = Selection.Create(GetRootPart())
Faces = PartSel.ConvertToFaces()
BoundingBox = Box.Create(MM(-30),MM(-30),MM(-30),MM(30),MM(30),MM(30))
FacesInBoundingBox = Faces.FilterByBoundingBox(BoundingBox)-Aniket
-
-
September 28, 2023 at 9:57 amchristian.schefflerSubscriber
Hi Aniket,
unfortunately the FilterByBoundingBox method is not working for me in V23. But I agree with you, the x, y, z order is correct for your example above.
public static Box Create( double minX, double minY, double minZ, double maxX, double maxY, double maxZ )
Please find a MWE below.
Probelm: In my case this does not limit the total set to the subset of faces.Best regards
Christian###
# Python Script, API Version = V23#*************************************# Geometry definition (dimensions in mm)#*************************************width= 2length= 100number_of_arms = 3#*********************************#Part2: Geometry generation#*********************************# 3 Arms# Set Sketch PlanesectionPlane = Plane.PlaneXYresult = ViewHelper.SetSketchPlane(sectionPlane, None)# EndBlock# Sketch Rectanglepoint1 = Point2D.Create(MM(width/2),MM(0))point2 = Point2D.Create(MM(-width/2),MM(0))point3 = Point2D.Create(MM(-width/2),MM(length))result = SketchRectangle.Create(point1, point2, point3)# EndBlock# Solidify Sketchmode = InteractionMode.Solidresult = ViewHelper.SetViewMode(mode, Info4)# EndBlock# Rotieren über Z-Griffselection = BodySelection.Create(GetRootPart().Bodies[:])anchor = CoordinateSystem1axis = Move.GetAxis(anchor)options = MoveOptions()options.CreatePatterns = Trueangle=360/number_of_armsresult = Move.Rotate(selection, axis, DEG(angle), options, Info13)# EndBlock# Circle# Set Sketch PlanesectionPlane = Plane.PlaneXYresult = ViewHelper.SetSketchPlane(sectionPlane, Info6)# EndBlock# Sketch Circleorigin = Point2D.Create(0,0)result = SketchCircle.Create(origin, MM(10))# EndBlock# Solidify Sketchmode = InteractionMode.Solidresult = ViewHelper.SetViewMode(mode, Info7)# EndBlock# Copy Elements out of Components (Pattern)selection = BodySelection.Create(GetRootPart().Components[0].Components[0].Content.Bodies[0])result = Copy.Execute(selection)selection = BodySelection.Create(GetRootPart().Components[0].Components[1].Content.Bodies[0])result = Copy.Execute(selection)selection = BodySelection.Create(GetRootPart().Components[0].Components[2].Content.Bodies[0])result = Copy.Execute(selection)# EndBlock# Delete Objects (Components)selection = ComponentSelection.Create(GetRootPart().Components[:])result = Delete.Execute(selection)# EndBlock# RenameGetRootPart().Bodies[0].SetName("Circle")GetRootPart().Bodies[1].SetName("Arm1")GetRootPart().Bodies[2].SetName("Arm2")GetRootPart().Bodies[3].SetName("Arm3")# EndBlock# Project to solidselection = FaceSelection.Create(GetRootPart().Bodies[0].Faces[:])target = FaceSelection.Create(GetRootPart().Bodies[1].Faces[:])direction = Selection.Create(GetRootPart())result = ProjectToSolid.Execute(selection, target, direction)# EndBlock# Project to solidselection = FaceSelection.Create(GetRootPart().Bodies[0].Faces[:])target = FaceSelection.Create(GetRootPart().Bodies[2].Faces[:])direction = Selection.Create(GetRootPart())result = ProjectToSolid.Execute(selection, target, direction)# EndBlock# Project to solidselection = FaceSelection.Create(GetRootPart().Bodies[0].Faces[:])target = FaceSelection.Create(GetRootPart().Bodies[3].Faces[:])direction = Selection.Create(GetRootPart())result = ProjectToSolid.Execute(selection, target, direction)# EndBlock#************************************************#Part 3: Selection of faces by different methods#*************************************************PartSel1 = Selection.Create(GetRootPart())Faces1 = PartSel1.ConvertToFaces()PartSel2 = Selection.Create(GetRootPart().Bodies[0])Faces2 = PartSel2.ConvertToFaces()Faces = Selection.Difference(Faces1,Faces2)BoundingBox = Box.Create(MM(-20),MM(-20),MM(-2),MM(20),MM(20),MM(2))FacesInBoundingBox = Faces.FilterByBoundingBox(BoundingBox)# FacesInBoundingBox contains all the faces of the 3 arms.# Expected was a selection of the 3 faces underneath the circle ONLYresult = Delete.Execute(FacesInBoundingBox) -
October 3, 2023 at 11:26 amAniketForum Moderator
Hi Christian,
Ansys employees can not run the codes they get on the forum, but I would recommend you to take the snippet that I shared and create some bodies randomly in your model and see if the bounding box method works, please note it will also select the faces if they are partially inside the bounding box.
-
October 4, 2023 at 10:45 amchristian.schefflerSubscriber
Hi Ankit,
thanks! The problem was that my bounding box intersects the outer areas which I didn’t want to be selected. That’s what I have overlooked in the method description.
A size reduction of bounding box helps in this case!Problem solved for versions >= ANSYS 2023R1 (v23)
-
- The topic ‘SpaceClaim Script: Selection by FilterByBoundingBox’ is closed to new replies.
- Data Center Simulation
- Unable to attach geometry 2024 R2
- Getting Mesh Faces With Specified Normal Via SpaceClaim Scripting (V241)
- How to provide blade angles in bladegen.
- DXF file loaded incorrectly
- plugin error failed to import assembly from spaceclaim
- Crash by using Script Editor
- Overlapping contact face
- Thermoelectric Cooler Model
- Temperature’s Distribution not available in Refine Mode ?
-
1216
-
543
-
523
-
225
-
209
© 2024 Copyright ANSYS, Inc. All rights reserved.