forked from youen/assembly_handbook
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.
122 lines
4.1 KiB
122 lines
4.1 KiB
from typing import Optional |
|
|
|
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: Optional[App.DocumentObject]): |
|
allStages = self.getAllStages() |
|
|
|
doc = App.ActiveDocument |
|
|
|
if part is not None and 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)
|
|
|