Curves workbench

Post here for help on using FreeCAD's graphical user interface (GUI).
Forum rules
and Helpful information
IMPORTANT: Please click here and read this first, before asking for help

Also, be nice to others! Read the FreeCAD code of conduct!
keithsloan52
Veteran
Posts: 2756
Joined: Mon Feb 27, 2012 5:31 pm

Re: Curves workbench

Post by keithsloan52 »

edwilliams16 wrote: Fri Dec 02, 2022 10:57 pm
keithsloan52 wrote: Fri Dec 02, 2022 9:41 pm
So, are you just trying to pick a point on the surface and put something there? Click on the ellipsoid, then

Code: Select all

sel = Gui.Selection.getSelectionEx()[0]
point = sel.PickedPoints[0]
surf = sel.SubObjects[0].Surface
u, v = surf.projectPoint(point, 'LowerDistanceParameters')
surf.value(u, v) # => location
surf.normal(u,v) # normal
surf.tangent(u, v) # tangent in u, v directions
But getSelection does not work that way, if two things have been selected you don't know which is [0] and which is [1]
it depends on which order the user selected them.

The problem with any objects implemented ( User or System) as FeaturePython they just return the same TypeId.
Sebastian Hoogen in the original OpenSCAD workbench set a Type variable in the Proxy and I have done the same in my
workbenches. In my mind there should be an agreed way in which such objects can be differentiated. Yes a lot of
people don't worry to take such things into consideration but I have to say they are defaulting to hack programming and
poor interface implementation [/rant off]
User avatar
Chris_G
Veteran
Posts: 2579
Joined: Tue Dec 31, 2013 4:10 pm
Location: France
Contact:

Re: Curves workbench

Post by Chris_G »

keithsloan52 wrote: Fri Dec 02, 2022 9:41 pm I need to check that one of the item in sel is an isocurve and another is a another specific type.

Code: Select all

from freecad.Curves.IsoCurve import IsoCurve

def is_IsoCurve(obj):
    if hasattr(obj, "Proxy") and isinstance(obj.Proxy, IsoCurve):
        return True
    return False

keithsloan52 wrote: Sat Dec 03, 2022 10:00 am Yes a lot of people don't worry to take such things into consideration but I have to say they are defaulting to hack programming and
poor interface implementation [/rant off]
From Curves Workbench Github Homepage :
This workbench is in ALPHA state and should NOT be used for any serious work.
This disclaimer is also valid for its API.
I have never claimed I was doing anything more than learning geometry and python programming.
I am not a software engineer.
Basing some tools of your workbench upon CurvesWB objects or API is an utterly bad decision to start with.
Pickup as much code of the CurvesWB as you want, don't create a dependency on it.
And that way, You will be able to add the Type property you are expecting.
keithsloan52
Veteran
Posts: 2756
Joined: Mon Feb 27, 2012 5:31 pm

Re: Curves workbench

Post by keithsloan52 »

Chris_G wrote: Sat Dec 03, 2022 10:49 am
keithsloan52 wrote: Fri Dec 02, 2022 9:41 pm I need to check that one of the item in sel is an isocurve and another is a another specific type.

Code: Select all

from freecad.Curves.IsoCurve import IsoCurve

def is_IsoCurve(obj):
    if hasattr(obj, "Proxy") and isinstance(obj.Proxy, IsoCurve):
        return True
    return False

Thanks
keithsloan52
Veteran
Posts: 2756
Joined: Mon Feb 27, 2012 5:31 pm

Re: Curves workbench

Post by keithsloan52 »

edwilliams16 wrote: Fri Dec 02, 2022 10:57 pm
keithsloan52 wrote: Fri Dec 02, 2022 9:41 pm
So, are you just trying to pick a point on the surface and put something there? Click on the ellipsoid, then

Code: Select all

sel = Gui.Selection.getSelectionEx()[0]
point = sel.PickedPoints[0]
surf = sel.SubObjects[0].Surface
u, v = surf.projectPoint(point, 'LowerDistanceParameters')
surf.value(u, v) # => location
surf.normal(u,v) # normal
surf.tangent(u, v) # tangent in u, v directions
I want to put an object on the surface everywhere the iso lines intersect. The objects Rotation part of Placement needs to be such that the object is normal to the surface
keithsloan52
Veteran
Posts: 2756
Joined: Mon Feb 27, 2012 5:31 pm

Re: Curves workbench

Post by keithsloan52 »

Okay have made some progress

Now need to sort out the normals to the surface at the intersection of the isocurves
F3253FBC-F475-46FD-9106-C6AFBCC3E88E.jpeg
F3253FBC-F475-46FD-9106-C6AFBCC3E88E.jpeg (99.1 KiB) Viewed 867 times
File before running macro
IsoCurve_Test.FCStd
(161.27 KiB) Downloaded 14 times
File after running macro
IsoCurve_Test-After.FCStd
(180.57 KiB) Downloaded 11 times
Current version of Macro
Test-ISO.FCMacro
(2.53 KiB) Downloaded 13 times
To run Macro first select GDMLBox_Box and the IsoCurve in Combo View

From the report view it looks like the IsoCurve Shape has no Faces? Is that correct?
Having got the points of intersection I was assuming I could then ask for the normal on the IsoCurve Face.
User avatar
onekk
Veteran
Posts: 6144
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: Curves workbench

Post by onekk »

keithsloan52 wrote: Sat Dec 03, 2022 5:21 pm ...
Having got the points of intersection I was assuming I could then ask for the normal on the IsoCurve Face.
Not probably you have to use u,v coordinates and get the normal of the surface.

Usually it is obtained with:

Code: Select all

vdir = surf.normalAt(u, v)
pos =  surf.valueAt(b_uv, b_vv)
...
rot = Rotation(Vector(0,0,1), vdir)
obj.rotate(Vector(0,0,0), rot.Axis, degrees(rot.Angle))
obj.translate(pos)   
Supposing the reference axis of obj is Z axis, see maybe:

https://forum.freecadweb.org/viewtopic. ... 88#p642188

Regards

Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
keithsloan52
Veteran
Posts: 2756
Joined: Mon Feb 27, 2012 5:31 pm

Re: Curves workbench

Post by keithsloan52 »

onekk wrote: Sat Dec 03, 2022 6:02 pm
keithsloan52 wrote: Sat Dec 03, 2022 5:21 pm ...
Having got the points of intersection I was assuming I could then ask for the normal on the IsoCurve Face.
Not probably you have to use u,v coordinates and get the normal of the surface.

Usually it is obtained with:

Code: Select all

vdir = surf.normalAt(u, v)
pos =  surf.valueAt(b_uv, b_vv)
...
rot = Rotation(Vector(0,0,1), vdir)
obj.rotate(Vector(0,0,0), rot.Axis, degrees(rot.Angle))
obj.translate(pos)   
Supposing the reference axis of obj is Z axis, see maybe:

https://forum.freecadweb.org/viewtopic. ... 88#p642188

Regards

Carlo D.
Thanks but where is the surface?

The IsoCurve is created on a GDMLObject not something from the Curves workbench. I used the Curves workbench to create the IsoCurve,
which it seems to have done correctly.

Not seeing a surface in the IsoCurve object, what am I missing?

Code: Select all

>>> doc = App.getDocument("IsoCurve_Test_After")
>>> obj = doc.getObject("IsoCurve")
>>> shp = obj.Shape
>>> ### End command Std_SendToPythonConsole
>>> print(dir(obj))
['Content', 'Document', 'ExpressionEngine', 'Face', 'FullName', 'ID', 'InList', 'InListRecursive', 'Label', 'Label2', 'MemSize', 'Mode', 'Module', 'MustExecute', 'Name', 'NoTouch', 'NumberU', 'NumberV', 'OldLabel', 'Orientation', 'OutList', 'OutListRecursive', 'Parameter', 'Parents', 'Placement', 'PropertiesList', 'Proxy', 'Removing', 'Shape', 'State', 'TypeId', 'ViewObject', 'Visibility', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'addExtension', 'addProperty', 'adjustRelativeLinks', 'clearExpression', 'dumpContent', 'dumpPropertyContent', 'enforceRecompute', 'evalExpression', 'getAllDerivedFrom', 'getDocumentationOfProperty', 'getEditorMode', 'getEnumerationsOfProperty', 'getGlobalPlacement', 'getGroupOfProperty', 'getLinkedObject', 'getParentGeoFeatureGroup', 'getParentGroup', 'getPaths', 'getPathsByOutList', 'getPropertyByName', 'getPropertyNameOfGeometry', 'getPropertyOfGeometry', 'getPropertyStatus', 'getPropertyTouchList', 'getStatusString', 'getSubObject', 'getSubObjectList', 'getSubObjects', 'getTypeIdOfProperty', 'getTypeOfProperty', 'hasChildElement', 'hasExtension', 'isDerivedFrom', 'isElementVisible', 'isValid', 'purgeTouched', 'recompute', 'removeProperty', 'resolve', 'resolveSubElement', 'restoreContent', 'restorePropertyContent', 'setDocumentationOfProperty', 'setEditorMode', 'setElementVisible', 'setExpression', 'setGroupOfProperty', 'setPropertyStatus', 'supportedProperties', 'touch']
>>> print(dir(shp))
['Area', 'BoundBox', 'CenterOfGravity', 'CompSolids', 'Compounds', 'Content', 'Edges', 'Faces', 'Length', 'MemSize', 'Module', 'Orientation', 'Placement', 'ShapeType', 'Shells', 'Solids', 'SubShapes', 'Tag', 'TypeId', 'Vertexes', 'Volume', 'Wires', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', 'add', 'ancestorsOfType', 'applyRotation', 'applyTranslation', 'check', 'childShapes', 'cleaned', 'common', 'complement', 'connectEdgesToWires', 'copy', 'countElement', 'countSubElements', 'cut', 'defeaturing', 'distToShape', 'dumpContent', 'dumpToString', 'exportBinary', 'exportBrep', 'exportBrepToString', 'exportIges', 'exportStep', 'exportStl', 'extrude', 'findPlane', 'fix', 'fixTolerance', 'fuse', 'generalFuse', 'getAllDerivedFrom', 'getElement', 'getElementTypes', 'getFaces', 'getFacesFromSubElement', 'getLines', 'getLinesFromSubElement', 'getPoints', 'getTolerance', 'globalTolerance', 'hashCode', 'importBinary', 'importBrep', 'importBrepFromString', 'inTolerance', 'isClosed', 'isCoplanar', 'isDerivedFrom', 'isEqual', 'isInfinite', 'isInside', 'isNull', 'isPartner', 'isSame', 'isValid', 'limitTolerance', 'makeChamfer', 'makeFillet', 'makeOffset2D', 'makeOffsetShape', 'makeParallelProjection', 'makePerspectiveProjection', 'makeShapeFromMesh', 'makeThickness', 'makeWires', 'mirror', 'multiFuse', 'nullify', 'oldFuse', 'optimalBoundingBox', 'overTolerance', 'project', 'proximity', 'read', 'reflectLines', 'removeInternalWires', 'removeShape', 'removeSplitter', 'replaceShape', 'restoreContent', 'reverse', 'reversed', 'revolve', 'rotate', 'rotated', 'scale', 'scaled', 'section', 'sewShape', 'slice', 'slices', 'tessellate', 'toNurbs', 'transformGeometry', 'transformShape', 'transformed', 'translate', 'translated', 'writeInventor']
>>> 
Wondering: Do I need to ask @Chris_G if he could add a property to the IsoCurve that is a Link to the Surface that was used to create the IsoCurve i.e. say OrigSurface - PropertyLinkGlobal property?
Last edited by keithsloan52 on Sat Dec 03, 2022 6:48 pm, edited 1 time in total.
User avatar
onekk
Veteran
Posts: 6144
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: Curves workbench

Post by onekk »

keithsloan52 wrote: Sat Dec 03, 2022 6:37 pm ...
Usually it is a subclass of Face

If you see in linked post, the whole code, I admit it is not clear.

Suppose you have a cylinder you have the "Curved surface" on Faces[0] so:

Code: Select all

face = cyl.faces[0]
surf = face.Surface
Usually will work.

But as I'm using my memory I could be wrong, sadly I've no time to test now.

Regards

Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
keithsloan52
Veteran
Posts: 2756
Joined: Mon Feb 27, 2012 5:31 pm

Re: Curves workbench

Post by keithsloan52 »

onekk wrote: Sat Dec 03, 2022 6:47 pm
keithsloan52 wrote: Sat Dec 03, 2022 6:37 pm ...
Usually it is a subclass of Face

If you see in linked post, the whole code, I admit it is not clear.

Suppose you have a cylinder you have the "Curved surface" on Faces[0] so:

Code: Select all

face = cyl.faces[0]
surf = face.Surface
Usually will work.

But as I'm using my memory I could be wrong, sadly I've no time to test now.

Regards

Carlo D.
But it looks like the IsoCurve does not contain or has a pointer to the Surface that was used to create it

Code: Select all

>>> print(len(obj.Shape.Faces))
0
keithsloan52
Veteran
Posts: 2756
Joined: Mon Feb 27, 2012 5:31 pm

Re: Curves workbench

Post by keithsloan52 »

Okay as a test I just tried changing the IsoCurve properties Number U and Number V through the properties editor but nothing changed.

Normally the OnChange function of the FeaturePython would be driven, so either there is no such function or it does not action because it does
not know how to access the original Surface. @Chris_G
Post Reply