[Link] of (Sketch)ObjectPython / Part FeaturePython lose its 'Proxy Methods' ?

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Post Reply
paullee
Veteran
Posts: 5097
Joined: Wed May 04, 2016 3:58 pm

[Link] of (Sketch)ObjectPython / Part FeaturePython lose its 'Proxy Methods' ?

Post by paullee »

Hi again!

I am testing Arch WB using a few feature including Link and other new features I am experimenting there. In the processing @Realthundar helped to resolve some bug / add some features :) ...
Link of Array Solid Subtraction Do Not Create Openings
Link Object (Sketch) has no separate MapMode/ Attachment Offset ?

Here is the current issue / usecase:-

(Sorry that I am not a programmer so I may have not used the exact terms or jargons)
...
  1. I am using SketchObjectPython and experimenting add methods to automatically recomputing its Attachment Offset (on top of MapMode) / Placement.
  2. Great Link helps to reproduce 'instance' of the SketchObjectPython Shape
  3. Great that Link allow to addExtension of the MapMode
  4. But the 'methods' of each 'instance' / Link of the SketchObjectPython seems not longer available?
  5. I am thinking each 'instance' / Link of the SketchObjectPython can determine its AttachmentOffset/Placement, whilst its shape are consistent
  6. One of the trick part maybe in the method() I use added object's property e.g. App::PropertyLink, App::PropertyString so that these should be 'instance / Link' - specific
> SketchObjectPython + Method() to calculate its AttachmentOffset / Placement
- 'Instance / Link 1' to SketchObjectPython + Method() to calculate THIS INSTANCE's AttachmentOffset / Placement
- 'Instance / Link 2' to SketchObjectPython + Method() to calculate THIS INSTANCE's AttachmentOffset / Placement
- ...

Similarly, Part:FeaturePython objects like Arch object has not longer access to the Methods()

Code: Select all

App.ActiveDocument.addObject("Sketcher::SketchObjectPython",name)	

class ArchSketch():

  def __init__(self, obj):
      obj.addProperty("App::PropertyLink","MasterSketch","Reference ","Master Sketch to Attach on")
      obj.addProperty("App::PropertyString","MasterSketchSubelement","Reference","Master Sketch Sub-Element to Attach on")
      return None								
										
  def execute(self, fp):							

      ''' Methods to calculate its AttachmentOffset in MapMode '''			
      fp.recompute()								

realthunder wrote: Sorry to Ping you again ! :)
[EDIT:
Likewise, a Link has ElementCount but similarly each of the 'Element' only has 'hardcode-input' Placement for individual 'Instance' / Link but no 'methods' to automatically calculate it ...]

Thanks for any idea to do that usecase / circumvent it ?


p.s.
This may go into Help or better Python scripting and macros?
vocx
Veteran
Posts: 5197
Joined: Thu Oct 18, 2018 9:18 pm

Re: [Link] of (Sketch)ObjectPython / Part FeaturePython lose its 'Proxy Methods' ?

Post by vocx »

paullee wrote: Sun Jan 05, 2020 1:41 am

Code: Select all

  def __init__(self, obj):
      obj.addProperty("App::PropertyLink","MasterSketch","Reference ","Master Sketch to Attach on")
      obj.addProperty("App::PropertyString","MasterSketchSubelement","Reference","Master Sketch Sub-Element to Attach on")
      return None								
I don't understand much of what you are saying. It hurts my head.

I just want to say, you shouldn't return None from __init__. This function is used to initialize the class. If you return from it, I'm afraid that the other methods of the class, execute and all, won't run.
Always add the important information to your posts if you need help. Also see Tutorials and Video tutorials.
To support the documentation effort, and code development, your donation is appreciated: liberapay.com/FreeCAD.
realthunder
Veteran
Posts: 2190
Joined: Tue Jan 03, 2017 10:55 am

Re: [Link] of (Sketch)ObjectPython / Part FeaturePython lose its 'Proxy Methods' ?

Post by realthunder »

It's not clear to me what you want to achieve. If you want to implement some special logic for handling instance of sketch, then you should create a custom Link object (the easiest one to use is App::LinkPython) that is only meant to link to sketch object. You can access the linked object and all its method through obj.LinkedObject. Or use Macro instead of creating custom object (unless you want to create a workbench). For Macro, it is the same, that is, you can access the linked object with the property 'LinkedObject'.
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
paullee
Veteran
Posts: 5097
Joined: Wed May 04, 2016 3:58 pm

Re: [Link] of (Sketch)ObjectPython / Part FeaturePython lose its 'Proxy Methods' ?

Post by paullee »

Sorry to confuse everybody :)

I search about App::LinkPython and have first look at the Assembly3 preview particularly @easyw-fc's example... need to test but seem not exactly the usecase here.

Would to try explain with the model I am building at Villa Savoye

Look at 1st picture below, the intended usecase is simplified below -

Modeling without Link
  1. There are a nos. of Door (Part::FeaturePython) objects created
  2. There is a Sketch with a nos. of edge in white colour representing a floor layout / layout of wall (see last picture)
  3. I am experimenting a method() which let the Door to 'attach' to edges of the Sketch Layout
  4. The method() take 2 edges from the user and calculate its intersection to place there
  5. So for each Doors, each position themselves according to the 2 edges input
  6. So when the Sketch Layout is changed, the Doors position follows to change
  7. The issue of this approach is creating redundant Object / Shape making file large
Modeling with Link ?
Instead of creating several copies of same Door, Link should help as known. Now, if I create a nos of Link to the same Door
  1. The Links of Door allow user to edit each of its Placement, ok.
  2. However, the method() of the original Door object is 'no longer available' to allow each of the Links to calculate each of their position
  3. I have to 'manually' calculate / move the door to the desired position
Hope it make myself clear :)

(Model attach at discussion thread there though may not help )
Screenshot from 2020-01-05 02-15-37.png
Screenshot from 2020-01-05 02-15-37.png (239.29 KiB) Viewed 3947 times
Screenshot from 2020-01-06 02-58-10.png
Screenshot from 2020-01-06 02-58-10.png (261.9 KiB) Viewed 3947 times
realthunder
Veteran
Posts: 2190
Joined: Tue Jan 03, 2017 10:55 am

Re: [Link] of (Sketch)ObjectPython / Part FeaturePython lose its 'Proxy Methods' ?

Post by realthunder »

So, how did you implement this 'method()'? Can you post the code here? This method() is not suitable to be implemented on SketchObjectPython. I'll see if I can change it to be a macro.
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
paullee
Veteran
Posts: 5097
Joined: Wed May 04, 2016 3:58 pm

Re: [Link] of (Sketch)ObjectPython / Part FeaturePython lose its 'Proxy Methods' ?

Post by paullee »

Thanks considering this usecase.

The ultimate objective of the experiment is to let Arch Objects to automatically 'relocate' itself. A method() to relocate itself is supposedly to add to the Arch Object, the framework of which is much simplified and outlined below.

Door 1........ Door 2........ Door 3........ Door ...
|________Host (Layout) Object_______|

( The method() I mention is not supposedly to be added to the 'Host' )

Code: Select all

'''  Simplified Conceptual Framework  '''


class _Window(ArchComponent.Component):

  # Arch Window also works as Door

  def __init__(self, obj):
      obj.addProperty("App::PropertyLink","MasterSketch","Reference ","Master Sketch to Attach on")
      obj.addProperty("App::PropertyString","MasterSketchSubelement","Reference","Master Sketch Sub-Element to Attach on")
										
  def execute(self, fp):

      ''' Update its AttachmentOffset in MapMode '''

      if fp.MasterSketch and fp.MasterSketchSubelement:
          tempAttachmentOffset = FreeCAD.Placement()

          ''' Get the Location and Angle of the Edge in the 'Host Sketch' to align the Door/Window Object

          tempAttachmentOffset.Base = self.getSketchEdgeLocation(fp.MasterSketch, fp.MasterSketchSubelement)
          tempAttachmentOffset.Rotation.Angle = getSketchEdgeAngle(fp.MasterSketch, fp.MasterSketchSubelement)

      fp.AttachmentOffset = tempAttachmentOffset
      fp.recompute()								


  def getSketchEdgeLocation(self, sketchEdge):
      ''' Method to calculate the Location '''

  def getSketchEdgeAngle(self, sketchEdge):
      ''' Method to calculate the Rotation '''
So now each Window/Door would update its Placement / AttachmentOffset to suit the 'Host' Object

But if Link to the Window/Door is created, the Link (replicates) no longer have this capability ?
realthunder
Veteran
Posts: 2190
Joined: Tue Jan 03, 2017 10:55 am

Re: [Link] of (Sketch)ObjectPython / Part FeaturePython lose its 'Proxy Methods' ?

Post by realthunder »

The following code is for a specialized LinkPython for _Window. The trick is to obtain the proxy of the linked object, and later on assign the AttachmentOffset of obj, instead of fp. BTW, without seeing the full code, I can't be sure. But it looks like you don't need AttachExtension in this case. Just compute the link's placement in the execute() and that's it.

Note, in most cases it does not make sense to call recompute() inside execute(), because 'execute()' is invoked by recompute() in the first place.

Code: Select all

class _WindowLink:

  def execute(self, obj):
        fp = obj.LinkedObject
      if not isinstance(getattr(fp,'Proxy',None), _Window):
          raise RuntimeError('Expected to link to Arch.Window object')
          
      if not hasExtension(obj, 'App::AttachExtension'):
          obj.addExtension('App::AttachExtensionPython')
                  
      if fp.MasterSketch and fp.MasterSketchSubelement:
          tempAttachmentOffset = FreeCAD.Placement()

          ''' Get the Location and Angle of the Edge in the 'Host Sketch' to align the Door/Window Object

          tempAttachmentOffset.Base = fp.Proxy.getSketchEdgeLocation(fp.MasterSketch, fp.MasterSketchSubelement)
          tempAttachmentOffset.Rotation.Angle = fp.Proxy.getSketchEdgeAngle(fp.MasterSketch, fp.MasterSketchSubelement)

      obj.AttachmentOffset = tempAttachmentOffset

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
paullee
Veteran
Posts: 5097
Joined: Wed May 04, 2016 3:58 pm

Re: [Link] of (Sketch)ObjectPython / Part FeaturePython lose its 'Proxy Methods' ?

Post by paullee »

realthunder wrote: Tue Jan 07, 2020 1:25 am The following code is for a specialized LinkPython for _Window.
Sorry I kind of understand the trick 'to obtain the proxy of the linked object', but trying hard understanding how the actual link is created with very limited prior programming knowledge for a while checking @easyw-fc 's example in the forum and your assembly 3 Link wiki.... with below codes ?

BTW, it seems then needs to create specialized complementary LinkPython for every type of Arch objects, e.g. Window, Wall, Structure, Roof, Panel etc... right ?

Just dreaming if a Link can have a dropdown dox to select the Linked Object's python methods, add_property()... etc. to run / add in the Links, so the Link get the same 'capabilities' of the original SketchObjectPython... FeaturePython ... etc. A twin not only in Shape but all 'behaviours' :lol:

Thanks.

Code: Select all

link = FreeCAD.ActiveDocument.addObject('App::LinkPython','LinkToWindow').setLink(WindowObject)
_WindowLink(link)
Another example in the wiki... use App::FeaturePython ... more difficult for me to understand :oops:

Code: Select all

...
def makeMyLink(obj):
    'make a link to the given object'

    # addObject() API is extended to accpet extra parameters in order to 
    # let the python object override the type of C++ view provider
    link = obj.Document.addObject("App::FeaturePython",'link',MyLink(),None,True)

    ViewProviderMyLink(link.ViewObject)

    link.setLink(obj)
    return link
User avatar
Zolko
Veteran
Posts: 2213
Joined: Mon Dec 17, 2018 10:02 am

Re: [Link] of (Sketch)ObjectPython / Part FeaturePython lose its 'Proxy Methods' ?

Post by Zolko »

realthunder wrote: Mon Jan 06, 2020 9:03 am you should create a custom Link object (the easiest one to use is App::LinkPython)
Is there some documentation on how to use this App::LinkPython object ? Do you think it could be a solution to my variant link question ?
try the Assembly4 workbench for FreCAD — tutorials here and here
realthunder
Veteran
Posts: 2190
Joined: Tue Jan 03, 2017 10:55 am

Re: [Link] of (Sketch)ObjectPython / Part FeaturePython lose its 'Proxy Methods' ?

Post by realthunder »

Zolko wrote: Wed Jan 08, 2020 3:18 pm you should create a custom Link object (the easiest one to use is App::LinkPython)
Is there some documentation on how to use this App::LinkPython object ? Do you think it could be a solution to my variant link question ?
This is just a Python extended version of App::Link, similar to what Part::FeaturePython to Part::Feature. Whether it is suitable for you or not depends on you need. Please elaborate, maybe in a separate post.
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
Post Reply