alright i have a basic example working.
- AWS_02_Basic_3Parts_with_Reuse.PNG (186.85 KiB) Viewed 5391 times
now i need to see if i can change the way link objects are inserted into the document, so that the file reference is
a property of the link, not
the identity of the link. this way, i can re-link the same file over and over, without having to save separate files with 1, 2, 3, 4 etc appended.
if the constraints then refer to the link ID, this can be unique, within the document.
the core of it worked though: i modeled parts in your new container, drew sketches on them where i wanted to attach them (and attach things
to them, put LCSs on these sketches (i'd like the option to skip that and use the sketches as the LCSs personally), and then your macro 'snapped' the chosen LCS pairs together, while keeping the 'root' object fixed.
then i change the middle piece, hit recompute of the assembly, and BOOM.
- AWS_03_Basic_3Parts_with_update.PNG (188.92 KiB) Viewed 5391 times
To me, this ability to model static assemblies parametrically with 100% stability (no solver) is what stood out immediately on hearing your proposal.
so i'd like to propose this:
-gather the base classes and set the needed additional properties in derived classes, or build the classes fresh from a python features.
-separate the identity of a file link within an assembly from the identity of the file it links
to.
-make sure the constraints refer to the link, not to the linked file.
-BOM stuff. super basic. rules for identifying components to prevent linking an assembly into itslef, and groundwork for complex BOM types.
-get rid of unique name issues, like 'Model'.
on that last topic, here is how i do it in my nurbs workbench.
here is an example command:
https://github.com/edwardvmills/Silk/bl ... Curve_4.py
The key to object creation starts around line 34:
Code: Select all
a=FreeCAD.ActiveDocument.addObject("Part::FeaturePython","CubicCurve_4")
AN.CubicCurve_4(a,poly)
a.ViewObject.Proxy=0 # just set it to something different from None (this assignment is needed to run an internal notification)
a.ViewObject.LineWidth = 1.00
a.ViewObject.LineColor = (1.00,0.67,0.00)
a.ViewObject.PointSize = 2.00
a.ViewObject.PointColor = (1.00,1.00,0.00)
FreeCAD.ActiveDocument.recompute()
i add an object 'a' to the document.
i pass a document tree name for that object, which is simply it's object type. if the name already exists, it just appends 001. i don't care.
i don't track the newly created object by it's document name. i track it by the variable i assigned the object
to at its creation: 'a'
i give that object as a parameter to AN.CubicCurve_4, which is my cubic curve class. i also pass the poly from the selection.
i don't need to add any properties. all the properties of CubicCurve_4 objects are defined in AN ahead of time.
i still have access to the object handle, 'a', so i take the opportunity to set a default visual aspect using the existing ViewObject properties of all 'simple' feature python objects.
so i have one GUI selection / document object creation file for
each workbench command, and one big library type file where i keep all the class definitions and function definitions. it uses FreeCAD modules at the lowest level possible, and doesn't even TOUCH selection processing or object creation. It could stand to get split into two or three, or ten pieces, but for now it feels comfy to have all my defs together (personally).
here is the corresponding definition for the function called above:
Code: Select all
class CubicCurve_4:
def __init__(self, obj , poly):
''' Add the properties '''
FreeCAD.Console.PrintMessage("\nCubicCurve_4 class Init\n")
obj.addProperty("App::PropertyLink","Poly","CubicCurve_4","control polygon").Poly = poly
obj.Proxy = self
def execute(self, fp):
'''Do something when doing a recomputation, this method is mandatory'''
# get the poles list from the poly. legacy shape function wants 'homogeneous' coords as [[x,y,z],w]
WeightedPoles=[[fp.Poly.Poles[0],fp.Poly.Weights[0]],
[fp.Poly.Poles[1],fp.Poly.Weights[1]],
[fp.Poly.Poles[2],fp.Poly.Weights[2]],
[fp.Poly.Poles[3],fp.Poly.Weights[3]]]
# the legacy function below sets the degree and knot vector
fp.Shape = Bezier_Cubic_curve(WeightedPoles).toShape()
the nice thing here is when i work on the function, i don't need to worry about the parameters. that is the workbench command's job
so if i were to try to help turn some of these into a workbench, i would like to use some aspects of this philosophy. specifically, separate the class and function definitions from all GUI selection processing and document object creation.
if you think this might lead to something useful to you, and the way you would like to see things run, let me know.
if we get this working, all the fancy pants constraint solver people
could create fancy pants non static fully defined constraint types, and then they could run a solver on those fancy pants constraints,
if they wanted to.
truth is, in solidworks, my end result for complex assemblies is completely nailed down with configurations. at the beginning, i let things slide around, rotate, etc. but once it gets serious, all subassemblies get nailed down to a few different configurations, those configurations then get nested in other configs, etc. the top level model with 1000s of parts is ALWAYS fully defined, and all states of interests can be quickly examined by switching configuration.
with 1000s of parts open at once, i don't trust for word censored that i can correctly push a cylinder rod to the true end of its travel just by dragging pixel in a 3D view, and then measure the correct resulting placement 20 parts over. but if i switch that cylinder to 'extended' config, then the assembly blinks to the new state, and measurements are valid, and so are interferences.