forked from youen/assembly_handbook
Merge pull request 'Divers fixes mineurs et annotations générées en cercle' (#2) from AndreasL/assembly_handbook:dev/better-annotations into master
Reviewed-on: youen/assembly_handbook#2
This commit is contained in:
commit
8bea399e48
@ -1,6 +1,7 @@
|
|||||||
import FreeCADGui as Gui
|
import FreeCADGui as Gui
|
||||||
import FreeCAD as App
|
import FreeCAD as App
|
||||||
|
|
||||||
|
import ahb_utils
|
||||||
class AHB_New_Step:
|
class AHB_New_Step:
|
||||||
def GetResources(self):
|
def GetResources(self):
|
||||||
return {"MenuText": "New Step",
|
return {"MenuText": "New Step",
|
||||||
@ -9,7 +10,7 @@ class AHB_New_Step:
|
|||||||
}
|
}
|
||||||
|
|
||||||
def IsActive(self):
|
def IsActive(self):
|
||||||
return True
|
return ahb_utils.getCurrentView() is not None
|
||||||
|
|
||||||
def Activated(self):
|
def Activated(self):
|
||||||
import re
|
import re
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
|
import math
|
||||||
import FreeCADGui as Gui
|
import FreeCADGui as Gui
|
||||||
import FreeCAD as App
|
import FreeCAD as App
|
||||||
|
|
||||||
|
import ahb_utils
|
||||||
|
|
||||||
class AHB_View_Annotate:
|
class AHB_View_Annotate:
|
||||||
def GetResources(self):
|
def GetResources(self):
|
||||||
return {"MenuText": "Annotate view",
|
return {"MenuText": "Annotate view",
|
||||||
@ -67,9 +70,75 @@ class AHB_View_Annotate:
|
|||||||
doc.removeObject(balloon.Name)
|
doc.removeObject(balloon.Name)
|
||||||
|
|
||||||
for partLink in view.XSource:
|
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)
|
workbench.techDrawExtensions.refreshOverlays(page)
|
||||||
|
|
||||||
|
|
||||||
|
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):
|
||||||
|
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
|
||||||
|
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
|
from ahb_command import AHB_CommandWrapper
|
||||||
AHB_CommandWrapper.addGuiCommand('AHB_view_annotate', AHB_View_Annotate())
|
AHB_CommandWrapper.addGuiCommand('AHB_view_annotate', AHB_View_Annotate())
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import FreeCADGui as Gui
|
import FreeCADGui as Gui
|
||||||
import FreeCAD as App
|
import FreeCAD as App
|
||||||
|
|
||||||
|
import ahb_utils
|
||||||
|
|
||||||
class AHB_EditViewSourceParts:
|
class AHB_EditViewSourceParts:
|
||||||
def GetResources(self):
|
def GetResources(self):
|
||||||
return {"MenuText": "Edit view source parts",
|
return {"MenuText": "Edit view source parts",
|
||||||
@ -19,9 +21,7 @@ class AHB_EditViewSourceParts:
|
|||||||
|
|
||||||
def Activated(self):
|
def Activated(self):
|
||||||
workbench = Gui.getWorkbench("AssemblyHandbookWorkbench") #: :type workbench: AssemblyHandbookWorkbench
|
workbench = Gui.getWorkbench("AssemblyHandbookWorkbench") #: :type workbench: AssemblyHandbookWorkbench
|
||||||
view = None
|
view = ahb_utils.getCurrentView()
|
||||||
if len(Gui.Selection.getSelection()) == 1 and Gui.Selection.getSelection()[0].TypeId == 'TechDraw::DrawViewPart':
|
|
||||||
view = Gui.Selection.getSelection()[0]
|
|
||||||
workbench.techDrawExtensions.toggleEditViewSourceParts(view)
|
workbench.techDrawExtensions.toggleEditViewSourceParts(view)
|
||||||
|
|
||||||
class AHB_AddSourcePartsToView:
|
class AHB_AddSourcePartsToView:
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import FreeCADGui as Gui
|
import FreeCADGui as Gui
|
||||||
import FreeCAD as App
|
import FreeCAD as App
|
||||||
|
|
||||||
|
import ahb_utils
|
||||||
class AHB_SetViewDirection:
|
class AHB_SetViewDirection:
|
||||||
def GetResources(self):
|
def GetResources(self):
|
||||||
return {"MenuText": "Set view direction",
|
return {"MenuText": "Set view direction",
|
||||||
@ -9,22 +10,15 @@ class AHB_SetViewDirection:
|
|||||||
}
|
}
|
||||||
|
|
||||||
def IsActive(self):
|
def IsActive(self):
|
||||||
view = self._get_view()
|
return ahb_utils.getCurrentView() is not None
|
||||||
return view is not None
|
|
||||||
|
|
||||||
def Activated(self):
|
def Activated(self):
|
||||||
workbench = Gui.getWorkbench("AssemblyHandbookWorkbench") #: :type workbench: AssemblyHandbookWorkbench
|
workbench = Gui.getWorkbench("AssemblyHandbookWorkbench") #: :type workbench: AssemblyHandbookWorkbench
|
||||||
view = self._get_view()
|
view = ahb_utils.getCurrentView()
|
||||||
if view is None:
|
if view is None:
|
||||||
raise Exception("Please select a TechDraw view")
|
raise Exception("Please select a TechDraw view")
|
||||||
workbench.techDrawExtensions.setCurrentViewDirection(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
|
from ahb_command import AHB_CommandWrapper
|
||||||
AHB_CommandWrapper.addGuiCommand('AHB_view_set_direction', AHB_SetViewDirection())
|
AHB_CommandWrapper.addGuiCommand('AHB_view_set_direction', AHB_SetViewDirection())
|
||||||
|
@ -457,6 +457,7 @@ class TechDrawExtensions:
|
|||||||
self.updating_balloon = False
|
self.updating_balloon = False
|
||||||
|
|
||||||
def add_or_update_balloon(self, view, part, parent_path):
|
def add_or_update_balloon(self, view, part, parent_path):
|
||||||
|
balloonsCreated = []
|
||||||
page = self.getViewPage(view)
|
page = self.getViewPage(view)
|
||||||
overlay_view = self.getOverlayView(view)
|
overlay_view = self.getOverlayView(view)
|
||||||
doc = page.Document
|
doc = page.Document
|
||||||
@ -498,14 +499,15 @@ class TechDrawExtensions:
|
|||||||
|
|
||||||
self.updateBalloon(balloon)
|
self.updateBalloon(balloon)
|
||||||
|
|
||||||
balloon.X = int(balloon.OriginX) + 20
|
|
||||||
balloon.Y = int(balloon.OriginY) + 20
|
|
||||||
|
|
||||||
if not self.isNewPartInView(view, part):
|
if not self.isNewPartInView(view, part):
|
||||||
balloon.ViewObject.Visibility = False
|
balloon.ViewObject.Visibility = False
|
||||||
|
else:
|
||||||
|
balloonsCreated.append(balloon)
|
||||||
else:
|
else:
|
||||||
self.updateBalloon(balloon)
|
self.updateBalloon(balloon)
|
||||||
|
|
||||||
|
return balloonsCreated
|
||||||
|
|
||||||
def updateBalloon(self, balloon):
|
def updateBalloon(self, balloon):
|
||||||
workbench = Gui.getWorkbench("AssemblyHandbookWorkbench") #: :type workbench: AssemblyHandbookWorkbench
|
workbench = Gui.getWorkbench("AssemblyHandbookWorkbench") #: :type workbench: AssemblyHandbookWorkbench
|
||||||
|
|
||||||
@ -524,7 +526,7 @@ class TechDrawExtensions:
|
|||||||
balloon.ViewObject.Font = 'DejaVu Sans'
|
balloon.ViewObject.Font = 'DejaVu Sans'
|
||||||
balloon.ViewObject.Fontsize = 4
|
balloon.ViewObject.Fontsize = 4
|
||||||
balloon.BubbleShape = 'Inspection'
|
balloon.BubbleShape = 'Inspection'
|
||||||
balloon.EndTypeScale = 1
|
balloon.EndTypeScale = 0.5
|
||||||
|
|
||||||
def getBalloonSourcePart(self, balloon):
|
def getBalloonSourcePart(self, balloon):
|
||||||
try:
|
try:
|
||||||
|
8
ahb_utils.py
Normal file
8
ahb_utils.py
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user