FreeCAD workbench to create assembly handbooks
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

120 lines
4.0 KiB

import FreeCADGui as Gui
import FreeCAD as App
from PySide.QtCore import QTimer
import random
def _rgb(r, g, b):
return r/255.0, g/255.0, b/255.0, 0.0
_colors = [
_rgb(94, 224, 174),
_rgb(223, 234, 70),
_rgb(35, 120, 200),
_rgb(188, 80, 33),
_rgb(26, 242, 69),
_rgb(13, 41, 107),
_rgb(153, 9, 52),
_rgb(211, 119, 0),
_rgb(34, 130, 7),
_rgb(221, 79, 249)
]
class AHB_Context:
_activeStageId: int = None
_allStagesVisible: bool = True
_animationActive: bool = False
_timeSinceLastStageUpdate: int = 0
def setActiveStage(self, stageId):
self._activeStageId = stageId
self._updateVisibility()
def getActiveStage(self):
return self._activeStageId
def getAllStages(self):
allStages = set()
doc = App.ActiveDocument
for obj in doc.Objects:
if obj.TypeId == 'Part::Feature':
if 'AssemblyHandbook_Stage' in obj.PropertiesList:
allStages.add(obj.AssemblyHandbook_Stage)
allStages = list(allStages)
allStages.sort()
return allStages
def onPartStageChanged(self, part: App.DocumentObject):
allStages = self.getAllStages()
doc = App.ActiveDocument
if not 'AssemblyHandbook_Stage' in part.PropertiesList:
part.ViewObject.ShapeColor = (0.8,0.8,0.8,0.0)
for obj in doc.Objects:
if obj.TypeId == 'Part::Feature':
if 'AssemblyHandbook_Stage' in obj.PropertiesList:
stageIndex = allStages.index(obj.AssemblyHandbook_Stage)
obj.ViewObject.ShapeColor = _colors[stageIndex % len(_colors)]
self._updateVisibility()
def setAllStagesVisible(self, allStagesVisible):
self._allStagesVisible = allStagesVisible
self._updateVisibility()
def getAllStagesVisible(self):
return self._allStagesVisible
def _updateVisibility(self):
activeStageId = self.getActiveStage()
doc = App.ActiveDocument
for obj in doc.Objects:
if obj.TypeId == 'Part::Feature':
if 'AssemblyHandbook_Stage' in obj.PropertiesList:
obj.ViewObject.Visibility = self._allStagesVisible or activeStageId is None or obj.AssemblyHandbook_Stage <= activeStageId
def setAnimationActive(self, animationActive):
if self._animationActive == animationActive: return
self._animationActive = animationActive
self._updateAnimation()
def getAnimationActive(self):
return self._animationActive
def _updateAnimation(self):
if not self._animationActive: return
allStages = self.getAllStages()
if len(allStages) > 1 and self._timeSinceLastStageUpdate >= 1000:
self._timeSinceLastStageUpdate = 0
activeStageId = self.getActiveStage() or 0
stageIndex = allStages.index(activeStageId) if activeStageId in allStages else 0
stageIndex = (stageIndex + 1) % len(allStages)
self.setActiveStage(allStages[stageIndex])
tickResolution = 33
import math
from pivy import coin
cam = Gui.ActiveDocument.ActiveView.getCameraNode()
"""rot = coin.SbRotation()
rot.setValue(coin.SbVec3f(0, 0, 1), math.pi * tickResolution / 1000.0)
nrot = cam.orientation.getValue() * rot
cam.orientation = nrot"""
center = coin.SbVec3f(1000,0,750)
v = cam.position.getValue() - center
v[2] = 0
dist = v.length()
height = cam.position.getValue()[2]
angle = math.atan2(v[1], v[0])
angle = angle + 0.3 * tickResolution / 1000.0
cam.position = coin.SbVec3f(center[0] + math.cos(angle)*dist, center[1] + math.sin(angle)*dist, height)
cam.pointAt(center, coin.SbVec3f(0,0,1))
self._timeSinceLastStageUpdate = self._timeSinceLastStageUpdate + tickResolution
QTimer.singleShot(tickResolution, self._updateAnimation)