Another approach to assembly solver (A2plus)

Discussion about the development of the Assembly workbench.
User avatar
kkremitzki
Posts: 1768
Joined: Thu Mar 03, 2016 9:52 pm
Location: Texas

Re: Another approach to assembly solver (A2plus)

Postby kkremitzki » Wed Apr 10, 2019 3:52 am

The long term fix of course is for me to fix my patch which caused this, but I need to make some changes elsewhere to preserve the behavior I made the patch for in the first place.
Like my FreeCAD work? I'd appreciate any level of support via Patreon, Liberapay, or PayPal! Read more about what I do at my blog.
kbwbe
Posts: 877
Joined: Tue Apr 10, 2018 3:12 pm
Location: Germany, near Köln (Cologne)

Re: Another approach to assembly solver (A2plus)

Postby kbwbe » Wed Apr 10, 2019 10:10 am

Hi all,

I just detected, that the new version string of FC0.18.1 also broke the solving of constraints.
This is fixed with A2plus version v0.4.14

Please update your A2plus WB.
KBWBE

https://github.com/kbwbe/A2plus
latest release: v0.4.29, installable via FreeCAD's addon manager
Tutorials:
Paul Randall: https://youtu.be/mnkecA9S7kc
anisim (deutsch): https://www.youtube.com/watch?v=vDcaFq6IEJM
m.cavallerin
Posts: 81
Joined: Wed May 30, 2018 6:59 pm

Re: Another approach to assembly solver (A2plus)

Postby m.cavallerin » Wed Apr 10, 2019 10:15 pm

Could be possible to add this functionality for a Top - Down Modelling?

https://www.youtube.com/watch?v=tvzAcA8KNg0


here's follow the Macro, but I'm sure some skilled man could improve it.

Code: Select all

import os
import a2p_importpart as update
import PartDesignGui


assemblyName = App.ActiveDocument.Name
sel = FreeCADGui.Selection.getSelection()


update.a2p_EditPartCommand.Activated(sel)
pathPart = App.ActiveDocument.FileName 

nameFile = App.ActiveDocument.Name	
fN = App.getDocument(nameFile) #dleggo la struttura del file

skPath = fN.Objects[0].sourceFile 
labelSk = fN.Objects[0].Label 

FreeCAD.openDocument (skPath)

nameSk = App.ActiveDocument.Name

obj = App.ActiveDocument.RootObjects

for i in obj:
	if i.Label == nameFile:
		 Gui.showObject(i)
	else:
		Gui.hideObject(i)
FreeCAD.ActiveDocument.save()

FreeCAD.setActiveDocument(nameFile)
update.a2p_UpdateImportedPartsCommand.Activated(labelSk)
FreeCAD.ActiveDocument.save()

FreeCAD.setActiveDocument(assemblyName)
update.a2p_UpdateImportedPartsCommand.Activated(sel)

FreeCAD.closeDocument (nameSk)
FreeCAD.closeDocument (nameFile)
User avatar
f3nix
Posts: 299
Joined: Sat May 30, 2015 11:58 am

Re: Another approach to assembly solver (A2plus)

Postby f3nix » Sat Apr 13, 2019 7:12 pm

Hi!
kbwbe wrote:
I hope this is right place to ask.

I have a problem with constraining one part in my test assembly.
No plane constraints are available for DTW50W_scanner (axial and circular work well). Any idea what might be wrong?

Test file attached.

A2plus version 0.4.15

Code: Select all

OS: Debian GNU/Linux buster/sid (KDE//usr/share/xsessions/plasma)
Word size of OS: 64-bit
Word size of FreeCAD: 64-bit
Version: 0.19.16474 (Git)
Build type: Debug
Branch: master
Hash: 746997e48411f22a150b95b6fdbb9b02cbe741d5
Python version: 2.7.16
Qt version: 5.11.3
Coin version: 4.0.0a
OCC version: 7.3.0
Locale: Polish/Poland (pl_PL)
Cheers,
Mateusz

UPDATE: Assembly 2 does not have any problem constraining this part...
Attachments
test_v1.FCStd
(114.9 KiB) Downloaded 15 times
kbwbe
Posts: 877
Joined: Tue Apr 10, 2018 3:12 pm
Location: Germany, near Köln (Cologne)

Re: Another approach to assembly solver (A2plus)

Postby kbwbe » Sat Apr 13, 2019 9:16 pm

f3nix wrote:
Sat Apr 13, 2019 7:12 pm
I have a problem with constraining one part in my test assembly.
No plane constraints are available for DTW50W_scanner (axial and circular work well). Any idea what might be wrong?

Cheers,
Mateusz
Hi Mateusz,
i had a look at your file. The problematic part (DTW50W_scanner) does not have plane faces. Everything what seems to be a plane face is a BSplineSurface object in reality. Therefore A2plus does not accept them.

A2plus does not support BSplineSurfaces at moment. (Assembly2 does...)

Have a look at the report view in the following screenshot..
.
BSplineSurfaces.png
BSplineSurfaces.png (186.99 KiB) Viewed 473 times
KBWBE

https://github.com/kbwbe/A2plus
latest release: v0.4.29, installable via FreeCAD's addon manager
Tutorials:
Paul Randall: https://youtu.be/mnkecA9S7kc
anisim (deutsch): https://www.youtube.com/watch?v=vDcaFq6IEJM
User avatar
f3nix
Posts: 299
Joined: Sat May 30, 2015 11:58 am

Re: Another approach to assembly solver (A2plus)

Postby f3nix » Sat Apr 13, 2019 10:04 pm

kbwbe wrote:
Sat Apr 13, 2019 9:16 pm
Hi Mateusz,
i had a look at your file. The problematic part (DTW50W_scanner) does not have plane faces. Everything what seems to be a plane face is a BSplineSurface object in reality. Therefore A2plus does not accept them.
Thank you for a _very quick_ answer! :) Now I can stop banging my head against the wall.
FYI the model comes from the manufacturer in IGES format.

kbwbe wrote: A2plus does not support BSplineSurfaces at moment. (Assembly2 does...)
Ok. I'll try to work around this.

Thank you for your great work! :)

Cheers,
Mateusz
User avatar
f3nix
Posts: 299
Joined: Sat May 30, 2015 11:58 am

Re: Another approach to assembly solver (A2plus)

Postby f3nix » Sat Apr 13, 2019 11:39 pm

I have come up with this hack but it does not work as expected yet. Do you have any pointers what else should be changed? It creates broken constraints.

Thank you!

Code: Select all

diff --git a/a2p_constraints.py b/a2p_constraints.py
index 01f7d1f..155d5cd 100644
--- a/a2p_constraints.py
+++ b/a2p_constraints.py
@@ -513,8 +513,20 @@ class PlaneConstraint(BasicConstraint):
         c = self.constraintObject
         plane1 = getObjectFaceFromName(self.ob1, c.SubElement1)
         plane2 = getObjectFaceFromName(self.ob2, c.SubElement2)
-        normal1 = plane1.Surface.Axis
-        normal2 = plane2.Surface.Axis
+        if str(plane1.Surface) == '<BSplineSurface object>':
+            plane_norm, plane_pos, error = fit_plane_to_surface1(plane1.Surface)
+            normal1 = FreeCAD.Vector(plane_norm[0], plane_norm[1], plane_norm[2])
+            Msg('Normal 1 - my:{}\n'.format(normal1))
+        else:
+            normal1 = plane1.Surface.Axis
+            Msg('Normal 1:{}\n'.format(normal1))
+        if str(plane2.Surface) == '<BSplineSurface object>':
+            plane_norm2, plane_pos2, error2 = fit_plane_to_surface1(plane2.Surface)
+            normal2 = FreeCAD.Vector(plane_norm2[0], plane_norm2[1], plane_norm2[2])
+            Msg('Normal 2 - my:{}\n'.format(normal2))
+        else:
+            normal2 = plane2.Surface.Axis
+            Msg('Normal 2:{}\n'.format(normal2))
         angle = math.degrees(normal1.getAngle(normal2))
         if angle <= 90.0:
             self.direction = "aligned"
diff --git a/a2plib.py b/a2plib.py
index cc8ef92..657a8fc 100644
--- a/a2plib.py
+++ b/a2plib.py
@@ -33,6 +33,9 @@ import sys
 import copy
 import platform
 from a2p_viewProviderProxies import *
+import numpy
+crossProduct = numpy.cross
+dotProduct = numpy.dot
 
 PYVERSION =  sys.version_info[0]
 
@@ -97,6 +100,14 @@ else:
     OPERATING_SYSTEM = "OTHER"
 
 
+def fit_plane_to_surface1( surface, n_u=3, n_v=3 ):
+    uv = sum( [ [ (u,v) for u in numpy.linspace(0,1,n_u)] for v in numpy.linspace(0,1,n_v) ], [] )
+    P = [ surface.value(u,v) for u,v in uv ] #positions at u,v points
+    N = [ crossProduct( *surface.tangent(u,v) ) for u,v in uv ] 
+    plane_norm = sum(N) / len(N) #plane's normal, averaging done to reduce error
+    plane_pos = P[0]
+    error = sum([ abs( dotProduct(p - plane_pos, plane_norm) ) for p in P ])
+    return plane_norm, plane_pos, error
 
 #------------------------------------------------------------------------------
 def to_bytes(tx):
@@ -604,6 +615,8 @@ def planeSelected( selection ):
             face = getObjectFaceFromName( selection.Object, subElement)
             if str(face.Surface) == '<Plane object>':
                 return True
+            elif str(face.Surface) == '<BSplineSurface object>':
+                return True
     return False
 #------------------------------------------------------------------------------
 def vertexSelected( selection ):
Cheers,
Mateusz
kbwbe
Posts: 877
Joined: Tue Apr 10, 2018 3:12 pm
Location: Germany, near Köln (Cologne)

Re: Another approach to assembly solver (A2plus)

Postby kbwbe » Sun Apr 14, 2019 10:53 am

f3nix wrote:
Sat Apr 13, 2019 11:39 pm
I have come up with this hack but it does not work as expected yet. Do you have any pointers what else should be changed? It creates broken constraints.

Cheers,
Mateusz
Hi Mateusz,
thank you for your effort. I reworked your code and implemented it to A2plus. Now it accepts (flat) BSplineSurfaces as plane references.
This is the commit, if you want to have a look at the changes...
https://github.com/kbwbe/A2plus/commit/ ... adac4d078d

Please update your A2plus WB to V0.4.16
KBWBE

https://github.com/kbwbe/A2plus
latest release: v0.4.29, installable via FreeCAD's addon manager
Tutorials:
Paul Randall: https://youtu.be/mnkecA9S7kc
anisim (deutsch): https://www.youtube.com/watch?v=vDcaFq6IEJM
triplus
Posts: 8754
Joined: Mon Dec 12, 2011 4:45 pm

Re: Another approach to assembly solver (A2plus)

Postby triplus » Sun Apr 14, 2019 2:06 pm

kbwbe wrote:
Sun Apr 14, 2019 10:53 am
f3nix wrote:
Sat Apr 13, 2019 11:39 pm
I have come up with this hack but it does not work as expected yet. Do you have any pointers what else should be changed? It creates broken constraints.

Cheers,
Mateusz
Hi Mateusz,
thank you for your effort. I reworked your code and implemented it to A2plus. Now it accepts (flat) BSplineSurfaces as plane references.
This is the commit, if you want to have a look at the changes...
https://github.com/kbwbe/A2plus/commit/ ... adac4d078d

Please update your A2plus WB to V0.4.16
Thanks to both of you.
User avatar
f3nix
Posts: 299
Joined: Sat May 30, 2015 11:58 am

Re: Another approach to assembly solver (A2plus)

Postby f3nix » Sun Apr 14, 2019 6:48 pm

kbwbe wrote:
Sun Apr 14, 2019 10:53 am
Please update your A2plus WB to V0.4.16
Thank you! :)
It works like a charm.
Credits should go to @hamish2014 for his fit_plane_to_surface1 function.

Have a nice one.

Cheers,
Mateusz