From 11116df87e901c6d23357aa933929cf957ecb23a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9as=20Livet?= Date: Thu, 24 Nov 2022 17:39:40 +0100 Subject: [PATCH 1/5] Part name used in sub assembly are now properly display Step view have CoerceView set to True by default --- ahb_cmd_new_step.py | 1 + ahb_techdraw_extensions.py | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ahb_cmd_new_step.py b/ahb_cmd_new_step.py index 8e924bf..4b29f4b 100644 --- a/ahb_cmd_new_step.py +++ b/ahb_cmd_new_step.py @@ -70,6 +70,7 @@ class AHB_New_Step: view = doc.addObject('TechDraw::DrawViewPart', 'View') view.Perspective = False + view.CoarseView = True view.addProperty("App::PropertyString", "Assembly_handbook_PreviousStepView", "Assembly_handbook") view.addProperty("App::PropertyBool", "Assembly_handbook_RasterView", "Assembly_handbook") view.Assembly_handbook_RasterView = raster_view diff --git a/ahb_techdraw_extensions.py b/ahb_techdraw_extensions.py index a6ada90..c57e86d 100644 --- a/ahb_techdraw_extensions.py +++ b/ahb_techdraw_extensions.py @@ -542,6 +542,8 @@ class TechDrawExtensions: return part.Document.Name + '#' + part.Name def isPartLink(self, obj): + if obj is None: + return False if obj.TypeId == 'App::Link': return True if obj.TypeId == 'Part::FeaturePython' and hasattr(obj, 'LinkedObject'): # variant link @@ -550,7 +552,7 @@ class TechDrawExtensions: def getPartDisplayName(self, obj): if self.isPartLink(obj): - linked_obj = obj.LinkedObject + linked_obj = obj.SourceObject if hasattr(obj, 'SourceObject') else obj.LinkedObject if 'Assembly_handbook_PartDisplayName' in linked_obj.PropertiesList: return linked_obj.Assembly_handbook_PartDisplayName else: From aaeea1784f58de0d79e3dd7c55bca447d93e4813 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9as=20Livet?= Date: Thu, 8 Dec 2022 09:41:37 +0100 Subject: [PATCH 2/5] Button are activated only if view is selected --- ahb_cmd_new_step.py | 3 ++- ahb_cmd_view_annotate.py | 4 +++- ahb_cmd_view_edit_source_parts.py | 6 +++--- ahb_cmd_view_set_direction.py | 12 +++--------- ahb_utils.py | 8 ++++++++ 5 files changed, 19 insertions(+), 14 deletions(-) create mode 100644 ahb_utils.py diff --git a/ahb_cmd_new_step.py b/ahb_cmd_new_step.py index 4b29f4b..074ea8e 100644 --- a/ahb_cmd_new_step.py +++ b/ahb_cmd_new_step.py @@ -1,6 +1,7 @@ import FreeCADGui as Gui import FreeCAD as App +import ahb_utils class AHB_New_Step: def GetResources(self): return {"MenuText": "New Step", @@ -9,7 +10,7 @@ class AHB_New_Step: } def IsActive(self): - return True + return ahb_utils.getCurrentView() is not None def Activated(self): import re diff --git a/ahb_cmd_view_annotate.py b/ahb_cmd_view_annotate.py index bc63c3d..a206935 100644 --- a/ahb_cmd_view_annotate.py +++ b/ahb_cmd_view_annotate.py @@ -1,6 +1,8 @@ import FreeCADGui as Gui import FreeCAD as App +import ahb_utils + class AHB_View_Annotate: def GetResources(self): return {"MenuText": "Annotate view", @@ -9,7 +11,7 @@ class AHB_View_Annotate: } def IsActive(self): - return True + return ahb_utils.getCurrentView() is not None def Activated(self): workbench = Gui.getWorkbench("AssemblyHandbookWorkbench") #: :type workbench: AssemblyHandbookWorkbench diff --git a/ahb_cmd_view_edit_source_parts.py b/ahb_cmd_view_edit_source_parts.py index e0747aa..b03c318 100644 --- a/ahb_cmd_view_edit_source_parts.py +++ b/ahb_cmd_view_edit_source_parts.py @@ -1,6 +1,8 @@ import FreeCADGui as Gui import FreeCAD as App +import ahb_utils + class AHB_EditViewSourceParts: def GetResources(self): return {"MenuText": "Edit view source parts", @@ -19,9 +21,7 @@ class AHB_EditViewSourceParts: def Activated(self): workbench = Gui.getWorkbench("AssemblyHandbookWorkbench") #: :type workbench: AssemblyHandbookWorkbench - view = None - if len(Gui.Selection.getSelection()) == 1 and Gui.Selection.getSelection()[0].TypeId == 'TechDraw::DrawViewPart': - view = Gui.Selection.getSelection()[0] + view = ahb_utils.getCurrentView() workbench.techDrawExtensions.toggleEditViewSourceParts(view) class AHB_AddSourcePartsToView: diff --git a/ahb_cmd_view_set_direction.py b/ahb_cmd_view_set_direction.py index d657491..c839e54 100644 --- a/ahb_cmd_view_set_direction.py +++ b/ahb_cmd_view_set_direction.py @@ -1,6 +1,7 @@ import FreeCADGui as Gui import FreeCAD as App +import ahb_utils class AHB_SetViewDirection: def GetResources(self): return {"MenuText": "Set view direction", @@ -9,22 +10,15 @@ class AHB_SetViewDirection: } def IsActive(self): - view = self._get_view() - return view is not None + return ahb_utils.getCurrentView() is not None def Activated(self): workbench = Gui.getWorkbench("AssemblyHandbookWorkbench") #: :type workbench: AssemblyHandbookWorkbench - view = self._get_view() + view = ahb_utils.getCurrentView() if view is None: raise Exception("Please select a TechDraw view") workbench.techDrawExtensions.setCurrentViewDirection(view) - def _get_view(self): - view = None if len(Gui.Selection.getSelection()) == 0 else Gui.Selection.getSelection()[0] - if view is not None and view.TypeId != 'TechDraw::DrawViewPart': - view = None - return view - from ahb_command import AHB_CommandWrapper AHB_CommandWrapper.addGuiCommand('AHB_view_set_direction', AHB_SetViewDirection()) diff --git a/ahb_utils.py b/ahb_utils.py new file mode 100644 index 0000000..6d66ff1 --- /dev/null +++ b/ahb_utils.py @@ -0,0 +1,8 @@ +import FreeCADGui as Gui + +def getCurrentView(): + currentSel = Gui.Selection.getSelection() + if len(currentSel) == 1 and currentSel[0].TypeId == 'TechDraw::DrawViewPart': + return currentSel[0] + else: + return None \ No newline at end of file From 7214c541f14d9295ff4f358d8c764670de1b5182 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9as=20Livet?= Date: Thu, 8 Dec 2022 09:42:12 +0100 Subject: [PATCH 3/5] Annotation balloon are regrouped and created in circle --- ahb_cmd_view_annotate.py | 63 ++++++++++++++++++++++++++++++++++++++ ahb_techdraw_extensions.py | 4 +-- 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/ahb_cmd_view_annotate.py b/ahb_cmd_view_annotate.py index a206935..a34d33e 100644 --- a/ahb_cmd_view_annotate.py +++ b/ahb_cmd_view_annotate.py @@ -1,3 +1,4 @@ +import math import FreeCADGui as Gui import FreeCAD as App @@ -73,5 +74,67 @@ class AHB_View_Annotate: workbench.techDrawExtensions.refreshOverlays(page) + regroupedBalloons = self.RegroupNearestSimilarBalloons(balloonsCreated) + self.PlaceBalloonsInCircle(regroupedBalloons) + + def CalculatePointsCenter(self, balloons): + totalX = 0 + totalY = 0 + for balloon in balloons: + realBalloon = balloon[0] if type(balloon) is list else balloon + totalX = totalX + int(realBalloon.OriginX) + totalY = totalY + int(realBalloon.OriginY) + return App.Base.Vector2d(totalX / len(balloons), totalY / len(balloons)) + + def IsSimilarBalloonNear(self, balloonA, balloonB): + MAX_DISTANCE_BETWEEN_REGROUPED_BALLOONS = 50 + if balloonA.Text == balloonB.Text: + pos = App.Base.Vector2d(balloonA.OriginX, balloonA.OriginY) + dist = pos.distance(App.Base.Vector2d(balloonB.OriginX, balloonB.OriginY)) + return dist < MAX_DISTANCE_BETWEEN_REGROUPED_BALLOONS + else: + return False + + def RegroupNearestSimilarBalloons(self, balloons): + regroupedBalloons = [] + for balloon in balloons: + nearestBalloons = [] + for otherBalloon in balloons: + if otherBalloon != balloon and self.IsSimilarBalloonNear(balloon, otherBalloon): + nearestBalloons.append(otherBalloon) + balloons.remove(otherBalloon) + if len(nearestBalloons) == 0: + regroupedBalloons.append(balloon) + else: + nearestBalloons.append(balloon) + regroupedBalloons.append(nearestBalloons) + return regroupedBalloons + + def PlaceBalloonsInCircle(self, balloons): + center = self.CalculatePointsCenter(balloons) + nbBalloons = len(balloons) + balloonPosStep = (math.pi * 2) / nbBalloons + for i in range(nbBalloons): + balloonPos = App.Base.Vector2d(center.x + 600 * math.cos(balloonPosStep * i), center.y + 600 * math.sin(balloonPosStep * i)) + # Find nearest arrow to avoid arrow crossing each other + smallestDistance = 0 + balloonToUse = None + for balloon in balloons: + realBalloon = balloon[0] if type(balloon) is list else balloon + dist = balloonPos.distance(App.Base.Vector2d(realBalloon.OriginX, realBalloon.OriginY)) + if smallestDistance == 0 or dist < smallestDistance: + smallestDistance = dist + balloonToUse = balloon + + if balloonToUse is not None: + balloons.remove(balloonToUse) + if type(balloonToUse) is list: + for realBalloon in balloonToUse: + realBalloon.X = balloonPos.x + realBalloon.Y = balloonPos.y + else: + balloonToUse.X = balloonPos.x + balloonToUse.Y = balloonPos.y + from ahb_command import AHB_CommandWrapper AHB_CommandWrapper.addGuiCommand('AHB_view_annotate', AHB_View_Annotate()) diff --git a/ahb_techdraw_extensions.py b/ahb_techdraw_extensions.py index c57e86d..1d7a0d3 100644 --- a/ahb_techdraw_extensions.py +++ b/ahb_techdraw_extensions.py @@ -457,6 +457,7 @@ class TechDrawExtensions: self.updating_balloon = False def add_or_update_balloon(self, view, part, parent_path): + balloonsCreated = [] page = self.getViewPage(view) overlay_view = self.getOverlayView(view) doc = page.Document @@ -498,8 +499,7 @@ class TechDrawExtensions: self.updateBalloon(balloon) - balloon.X = int(balloon.OriginX) + 20 - balloon.Y = int(balloon.OriginY) + 20 + balloonsCreated.append(balloon) if not self.isNewPartInView(view, part): balloon.ViewObject.Visibility = False From 1652f32504e9cf98dffabecee05c3c597705e3fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9as=20Livet?= Date: Fri, 16 Dec 2022 12:20:18 +0100 Subject: [PATCH 4/5] annotation arrows are now scaled at 0.5 --- ahb_techdraw_extensions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ahb_techdraw_extensions.py b/ahb_techdraw_extensions.py index 1d7a0d3..0d9acd6 100644 --- a/ahb_techdraw_extensions.py +++ b/ahb_techdraw_extensions.py @@ -524,7 +524,7 @@ class TechDrawExtensions: balloon.ViewObject.Font = 'DejaVu Sans' balloon.ViewObject.Fontsize = 4 balloon.BubbleShape = 'Inspection' - balloon.EndTypeScale = 1 + balloon.EndTypeScale = 0.5 def getBalloonSourcePart(self, balloon): try: From 90f3402437dc44d917bb882c8df18f507718ad26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9as=20Livet?= Date: Fri, 16 Dec 2022 12:20:53 +0100 Subject: [PATCH 5/5] anotation grouping : various fix --- ahb_cmd_view_annotate.py | 18 +++++++++++------- ahb_techdraw_extensions.py | 6 ++++-- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/ahb_cmd_view_annotate.py b/ahb_cmd_view_annotate.py index a34d33e..90d8641 100644 --- a/ahb_cmd_view_annotate.py +++ b/ahb_cmd_view_annotate.py @@ -12,7 +12,7 @@ class AHB_View_Annotate: } def IsActive(self): - return ahb_utils.getCurrentView() is not None + return True def Activated(self): workbench = Gui.getWorkbench("AssemblyHandbookWorkbench") #: :type workbench: AssemblyHandbookWorkbench @@ -70,13 +70,15 @@ class AHB_View_Annotate: doc.removeObject(balloon.Name) for partLink in view.XSource: - workbench.techDrawExtensions.add_or_update_balloon(view, partLink, '') - + balloonsCreated = workbench.techDrawExtensions.add_or_update_balloon(view, partLink, '') + if len(balloonsCreated) > 0: + regroupedBalloons = self.RegroupNearestSimilarBalloons(balloonsCreated) + self.PlaceBalloonsInCircle(regroupedBalloons) + #self.PlaceBalloonsInCircle(balloonsCreated) + workbench.techDrawExtensions.refreshOverlays(page) - regroupedBalloons = self.RegroupNearestSimilarBalloons(balloonsCreated) - self.PlaceBalloonsInCircle(regroupedBalloons) - + def CalculatePointsCenter(self, balloons): totalX = 0 totalY = 0 @@ -115,7 +117,9 @@ class AHB_View_Annotate: nbBalloons = len(balloons) balloonPosStep = (math.pi * 2) / nbBalloons for i in range(nbBalloons): - balloonPos = App.Base.Vector2d(center.x + 600 * math.cos(balloonPosStep * i), center.y + 600 * math.sin(balloonPosStep * i)) + xPos = round(center.x + 600 * math.cos(balloonPosStep * i)) + yPos = round(center.y + 600 * math.sin(balloonPosStep * i)) + balloonPos = App.Base.Vector2d(xPos, yPos) # Find nearest arrow to avoid arrow crossing each other smallestDistance = 0 balloonToUse = None diff --git a/ahb_techdraw_extensions.py b/ahb_techdraw_extensions.py index 0d9acd6..7336d69 100644 --- a/ahb_techdraw_extensions.py +++ b/ahb_techdraw_extensions.py @@ -499,12 +499,14 @@ class TechDrawExtensions: self.updateBalloon(balloon) - balloonsCreated.append(balloon) - if not self.isNewPartInView(view, part): balloon.ViewObject.Visibility = False + else: + balloonsCreated.append(balloon) else: self.updateBalloon(balloon) + + return balloonsCreated def updateBalloon(self, balloon): workbench = Gui.getWorkbench("AssemblyHandbookWorkbench") #: :type workbench: AssemblyHandbookWorkbench