assembly without solver

Discussion about the development of the Assembly workbench.
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
User avatar
Zolko
Veteran
Posts: 2213
Joined: Mon Dec 17, 2018 10:02 am

Re: assembly without solver

Post by Zolko »

Code: Select all

void PropertyData::addProperty(...)

I belive this addProperty shoud be usable to add custom text fields to any object. And it seems accessible from python.

Code: Select all

>>> placement.addProperty('App::PropertyString','tata')
Traceback (most recent call last):
  File "<input>", line 1, in <module>
RuntimeError: Type App::Placement cannot dynamically add properties
>>> 

... but not for this things. It doesn't really matter though, because there is another feature App::FeaturePython to which we can add all sorts of properties, includung App::Placement and App::PropertyString. also App::PropertyPath should we need it

Code: Select all

>>> App.activeDocument().getObject('Constraints').newObject( 'App::FeaturePython', constrName )
>>> App.activeDocument().getObject( constrName ).addProperty('App::PropertyPlacement','Offset')
>>> App.activeDocument().getObject( constrName ).addProperty('App::PropertyString','Expression')
if I manage to write the expression string into this App::FeaturePython, what would be the syntax to evaluate it in the expression box ? The string itself can be accessed with

Code: Select all

>>> constrName.Expression
try the Assembly4 workbench for FreCAD — tutorials here and here
realthunder
Veteran
Posts: 2190
Joined: Tue Jan 03, 2017 10:55 am

Re: assembly without solver

Post by realthunder »

Zolko wrote: Mon Jan 28, 2019 2:17 pm This is a useful functionality, but quite an ad-hoc hack, don't you think ? If it was my money, I wouldn't bet on this horse.
No, that's not a hack. That is the FC standard way of making a Python binding object. Those App::XXXXPython object are all constructed this way. And only those objects support adding dynamic property using addProperty().
Zolko wrote: Mon Jan 28, 2019 3:09 pm if I manage to write the expression string into this App::FeaturePython, what would be the syntax to evaluate it in the expression box ?

Code: Select all

eval(constrName.Expression)
And if you have named variables in your expression, say v1, v2, or any other names, then

Code: Select all

eval(constrName.Expression, v1=something, v2=something)
Try Assembly3 with my custom build of FreeCAD at here.
And if you'd like to show your support, you can donate through patreon, liberapay, or paypal
User avatar
Zolko
Veteran
Posts: 2213
Joined: Mon Dec 17, 2018 10:02 am

Re: assembly without solver

Post by Zolko »

realthunder wrote: Mon Jan 28, 2019 10:25 pm

Code: Select all

eval(constrName.Expression)
yeah, that works, thank-you. What I do now when creating a link is the following:

  • create the App::Link to the selected model, called linkName
  • create an App::FeaturePython in the Constraints group of the model, called CSTR_linkName
  • add an App::Placement to it, called Offset (because that's what it is)
  • add 3 App::PropertyString text fields to store the name of the attachment part (parent assembly or sister par) Attachment_Part, the name of the attachment LCS in that attachment part Attachment_LCS, and the name of the link LCS in the linked part Link_LCS
  • add an App::PropertyString text field that stores the expression to be evaluated by the expression engine, Expression
  • populate the expression, that's where the heavy lifting happens: App.activeDocument().getObject( constrName ).Expression = '<<'+App.activeDocument().getObject( constrName ).Attachment_Part+'>>.Placement.multiply( <<'+App.activeDocument().getObject( constrName ).Attachment_Part+'>>.<<'+App.activeDocument().getObject( constrName ).Attachment_LCS+'.>>.Placement ).multiply( '+constrName+'.Offset ).multiply( .<<'+App.activeDocument().getObject( constrName ).Link_LCS+'.>>.Placement.inverse() )'
  • set the expression engine of the App::Link to point to the expression field:
    App.activeDocument().getObject( linkName ).setExpression('Placement', u'eval('+constrName+'.Expression)')

after creating the link, I manually adjust the Expression field ... it's super ugly. What's more, the 3 fields become useless and don't hold the real information that the expression uses: it's horrible. I'm eagerly waiting for fosselius' GUI


CSTR.png
CSTR.png (272.24 KiB) Viewed 3338 times


And if you have named variables in your expression, say v1, v2, or any other names, then

Code: Select all

eval(constrName.Expression, v1=something, v2=something)
I didn't manage to make this one work. The expression wants to be defined in the Expression field of the CSTR, though I can build it there from the informations stored in the other fields of the CSTR. I must be doing something wrong, but I don't know further. My macro for automating this is attached.
Attachments
link_Model.FCMacro
(3.17 KiB) Downloaded 96 times
try the Assembly4 workbench for FreCAD — tutorials here and here
User avatar
fosselius
Posts: 381
Joined: Sat Apr 23, 2016 10:03 am
Contact:

Re: assembly without solver

Post by fosselius »

Zolko wrote: Tue Jan 29, 2019 11:39 am What's more, the 3 fields become useless and don't hold the real information that the expression uses: it's horrible. I'm eagerly waiting for fosselius' GUI
I will see what i can do. Will try to repeat the steps you mentioned in the script.

1. What 3 fields?
2. Are you using modified source?
User avatar
Zolko
Veteran
Posts: 2213
Joined: Mon Dec 17, 2018 10:02 am

Re: assembly without solver

Post by Zolko »

fosselius wrote: Tue Jan 29, 2019 3:44 pm 1. What 3 fields?
the 3 custom text fields that I add to each Cosntraint to each part, and that allow to populate the expression stored in a 4th field (unsurprisingly called Expression)

Code: Select all

App.activeDocument().getObject( constrName ).addProperty('App::PropertyString','Attachment_Part','Placement')
App.activeDocument().getObject( constrName ).addProperty('App::PropertyString','Attachment_LCS','Placement')
App.activeDocument().getObject( constrName ).addProperty('App::PropertyString','Link_LCS','Placement')

App.activeDocument().getObject( constrName ).Attachment_Part = 'Model'
App.activeDocument().getObject( constrName ).Attachment_LCS = 'LCS_0'
App.activeDocument().getObject( constrName ).Link_LCS = 'LCS_0'
2. Are you using modified source?
I use the latest Asm3 AppImage
try the Assembly4 workbench for FreCAD — tutorials here and here
User avatar
Zolko
Veteran
Posts: 2213
Joined: Mon Dec 17, 2018 10:02 am

Re: assembly without solver

Post by Zolko »

fosselius wrote: Mon Jan 28, 2019 12:27 pm And latest import script is here:
https://gitlab.com/maidenOne/freecad_le ... nk.FCMacro

Note, its not yet functional, but its close.
I've taken your script, and made it (sort-of) work. I had to use a QListWidget and not the QListView you rprovided, because I was not able to get the selected item. This means also that I haven't been able to keep the filter function you have implemented (and that I very much like: with an assembly of hundreds of pieces, such a filter would be life-saving).

link_Model.png
link_Model.png (255.24 KiB) Viewed 3166 times

As can be seen, this doesn't list the current (active) document's object, I think it's a dangerous thing to do (potential for an infinite loop link loop). Now, what remains to do is a GUI to place the link and populate the expression engine.
Attachments
link_Model.FCMacro
(5.78 KiB) Downloaded 67 times
try the Assembly4 workbench for FreCAD — tutorials here and here
User avatar
fosselius
Posts: 381
Joined: Sat Apr 23, 2016 10:03 am
Contact:

Re: assembly without solver

Post by fosselius »

Zolko wrote: Sat Feb 02, 2019 3:17 pm
I will review and see if i can reintroduce the filtering.
Have been a bit busy with my new job.

Are reviewing a PCB to a machine that analyzes blood from infants. ^_^
User avatar
Zolko
Veteran
Posts: 2213
Joined: Mon Dec 17, 2018 10:02 am

Re: assembly without solver

Post by Zolko »

This assembly has ~130 parts ... I'm thinking of a Lego challenge, a collaborative one, with a Git repo. (the ZIP is too large, 2.2Mb, the bricks alone make 2.1Mb !!!)

Lego_House+Garden.png
Lego_House+Garden.png (340.85 KiB) Viewed 3073 times
try the Assembly4 workbench for FreCAD — tutorials here and here
User avatar
fosselius
Posts: 381
Joined: Sat Apr 23, 2016 10:03 am
Contact:

Re: assembly without solver

Post by fosselius »

Sweet! Will need to create that "LEGO move" tool soon ^_^
User avatar
Zolko
Veteran
Posts: 2213
Joined: Mon Dec 17, 2018 10:02 am

Re: assembly without solver

Post by Zolko »

fosselius wrote: Tue Feb 05, 2019 5:19 am Sweet! Will need to create that "LEGO move" tool soon ^_^
here, if these can help:
  • new_Model will create a new App::Part called Model with some default objects
  • new_LCS will create a new PartDesign::Coordinate system
  • link_Model will create a new App::Link and allow to choose the name and linked App::Part, and create default objects for the placement
  • place_Link will allow to place the App::Link by choosing an attachment LCS
  • place_LCS allows to attach an LCS to another LCS in another part (linked by App::Link). This is necessary for nested assemblies. This is not the same as Map Mode, which only works on local features.
So the workflow is the following:
  • create a new Model
  • if you have already a Body somewhere, copy that Body from your document, move it to the Model (App::Part) container
  • create LCS in the Model container (NOT in the Body)
  • put your LCS by choosing the Map Mode and attach it to whatever you want, including geometry in the Body
  • save document (App::Link only works with files saved before. You might need to close and re-open the document)
  • create a new Model
  • save document (App::Link only works with files saved before. You might need to close and re-open the document)
  • link_Model your first Model (this will place it to the default LCS_0 in each Model)
  • place_Link, which will allow you to attach your linked Model to any attachment LCS you have previously created
  • if the linked Model is at the correct place but badly oriented, select the constraint associated with it, and edit the App::Placement property called "Offset"
  • :o

You can try with the attached asm_Bricks and its only child brick_4x2_clear, to be placed in the same directory. Don't hesitate to try-out and to report problems (or successes)
Attachments
asm_Bricks.fcstd
(9.29 KiB) Downloaded 73 times
brick_4x2_clear.fcstd
(433.1 KiB) Downloaded 91 times
Macros.zip
(19.91 KiB) Downloaded 95 times
try the Assembly4 workbench for FreCAD — tutorials here and here
Post Reply