39 from PySide2.QtWidgets
import QDialogButtonBox
40 from PySide2.QtWidgets
import QMessageBox
41 from PySide2.QtCore
import QObject
42 from bisect
import bisect
47 PATH_TO_ICONS = path.join(FreeCAD.getHomePath(),
"Mod",
"Animate",
"Resources",
51 PATH_TO_UI = path.join(FreeCAD.getHomePath(),
"Mod",
"Animate",
"Resources",
88 super(TrajectoryPanel, self).
__init__()
94 for trajectory
in trajectories:
96 for prop
in trajectory.PropertiesList:
97 trajectory.setEditorMode(prop, 1)
99 trajectory.setEditorMode(
"Placement", 2)
100 trajectory.setEditorMode(
"ValidTrajectory", 2)
107 for i
in range(len(forms)):
108 forms[i].sld_time.valueChanged.connect(
109 lambda value, form=forms[i],
110 trajectory=trajectories[i]:
112 val = (100 * (trajectories[i].Time
113 - trajectories[i].Timestamps[0])) / \
114 (trajectory.Timestamps[-1]
115 - trajectory.Timestamps[0])
116 forms[i].sld_time.setValue(val)
132 t = value * (trajectory.Timestamps[-1]
133 - trajectory.Timestamps[0]) / 100 \
134 + trajectory.Timestamps[0]
139 form.lbl_time.setText(
"Time: " + (
"%5.3f" % t))
140 FreeCAD.ActiveDocument.recompute()
141 FreeCADGui.updateGui()
152 for prop
in trajectory.PropertiesList:
153 trajectory.setEditorMode(prop, 0)
154 trajectory.ViewObject.Proxy.panel =
None 157 trajectory.setEditorMode(
"ObjectPlacement", 1)
158 trajectory.setEditorMode(
"ParentFramePlacement", 1)
161 trajectory.setEditorMode(
"Placement", 2)
162 trajectory.setEditorMode(
"ValidTrajectory", 2)
163 FreeCADGui.Control.closeDialog()
178 FreeCAD.ActiveDocument.recompute()
179 FreeCADGui.updateGui()
198 return QDialogButtonBox.Ok | QDialogButtonBox.Cancel
280 fp.Timestamps, fp.TranslationX, fp.TranslationY,
281 fp.TranslationZ, fp.RotationPointX, fp.RotationPointY,
282 fp.RotationPointZ, fp.RotationAxisX, fp.RotationAxisY,
283 fp.RotationAxisZ, fp.RotationAngle)
285 if traj_valid != fp.ValidTrajectory:
286 fp.ValidTrajectory = traj_valid
288 elif prop ==
"Placement":
290 if hasattr(fp,
"Group")
and len(fp.Group) != 0:
291 for child
in fp.Group:
292 child.ParentFramePlacement = fp.Placement
297 if hasattr(fp,
"AnimatedObjects")
and len(fp.AnimatedObjects) != 0:
298 for o
in fp.AnimatedObjects:
299 o.Placement = fp.Placement
302 elif prop ==
"ParentFramePlacement":
304 fp.Placement = fp.ParentFramePlacement.multiply(
318 if not fp.ValidTrajectory:
319 FreeCAD.Console.PrintWarning(fp.Name +
".execute(): Trajectory " +
320 "is not in a valid format.\n")
326 self.
pose[
"position"] = (weights[0]*fp.TranslationX[indices[0]] +
327 weights[1]*fp.TranslationX[indices[1]],
328 weights[0]*fp.TranslationY[indices[0]] +
329 weights[1]*fp.TranslationY[indices[1]],
330 weights[0]*fp.TranslationZ[indices[0]] +
331 weights[1]*fp.TranslationZ[indices[1]])
332 self.
pose[
"rot_axis"] = (weights[0]*fp.RotationAxisX[indices[0]]
333 + weights[1]*fp.RotationAxisX[indices[1]],
334 weights[0]*fp.RotationAxisY[indices[0]]
335 + weights[1]*fp.RotationAxisY[indices[1]],
336 weights[0]*fp.RotationAxisZ[indices[0]]
337 + weights[1]*fp.RotationAxisZ[indices[1]])
338 self.
pose[
"rot_point"] = (weights[0]*fp.RotationPointX[indices[0]]
339 + weights[1]*fp.RotationPointX[indices[1]],
340 weights[0]*fp.RotationPointY[indices[0]]
341 + weights[1]*fp.RotationPointY[indices[1]],
342 weights[0]*fp.RotationPointZ[indices[0]]
343 + weights[1]*fp.RotationPointZ[indices[1]])
344 self.
pose[
"rot_angle"] = (weights[0]*fp.RotationAngle[indices[0]]
345 + weights[1]*fp.RotationAngle[indices[1]])
347 fp.ObjectPlacement = FreeCAD.Placement(
348 FreeCAD.Vector(self.
pose[
"position"][0],
349 self.
pose[
"position"][1],
350 self.
pose[
"position"][2]),
351 FreeCAD.Rotation(FreeCAD.Vector(self.
pose[
"rot_axis"][0],
352 self.
pose[
"rot_axis"][1],
353 self.
pose[
"rot_axis"][2]),
354 self.
pose[
"rot_angle"]),
355 FreeCAD.Vector(self.
pose[
"rot_point"][0],
356 self.
pose[
"rot_point"][1],
357 self.
pose[
"rot_point"][2],))
358 fp.Placement = fp.ParentFramePlacement.multiply(
372 fp.ViewObject.Proxy.setProperties(fp.ViewObject)
386 self.
pose = {
"position": (0, 0, 0),
387 "rot_axis": (0, 0, 0),
388 "rot_point": (0, 0, 0),
393 if not hasattr(fp,
"ValidTrajectory"):
394 fp.addProperty(
"App::PropertyBool",
"ValidTrajectory",
"General",
395 "This property records if trajectory was changed." 396 ).ValidTrajectory =
False 397 if not hasattr(fp,
"AnimatedObjects"):
398 fp.addProperty(
"App::PropertyLinkListGlobal",
"AnimatedObjects",
399 "General",
"Objects that will be animated.")
400 if not hasattr(fp,
"Interpolate"):
401 fp.addProperty(
"App::PropertyBool",
"Interpolate",
"General",
402 "Interpolate trajectory between timestamps." 404 if not hasattr(fp,
"AllowServer"):
405 fp.addProperty(
"App::PropertyBool",
"AllowServer",
"General",
406 "Should this object allow a Server object to " 407 +
"change it.").AllowServer =
True 408 if not hasattr(fp,
"AllowControl"):
409 fp.addProperty(
"App::PropertyBool",
"AllowControl",
"General",
410 "Should this object allow a Control object " 412 ).AllowControl =
True 413 if not hasattr(fp,
"Time"):
414 fp.addProperty(
"App::PropertyFloat",
"Time",
"General",
415 "Animation time in seconds.").Time = 0
416 if not hasattr(fp,
"ParentFramePlacement"):
417 fp.addProperty(
"App::PropertyPlacement",
"ParentFramePlacement",
418 "General",
"Current placement of a Parent Frame.")
419 if not hasattr(fp,
"ObjectPlacement"):
420 fp.addProperty(
"App::PropertyPlacement",
"ObjectPlacement",
422 "Current Object placement in a Parent Frame.")
425 if not hasattr(fp,
"Timestamps"):
426 fp.addProperty(
"App::PropertyFloatList",
"Timestamps",
427 "Trajectory",
"Timestamps at which we define\n" +
428 "translation and rotation.")
429 if not hasattr(fp,
"TranslationX"):
430 fp.addProperty(
"App::PropertyFloatList",
"TranslationX",
432 "Object translation along global X direction.")
433 if not hasattr(fp,
"TranslationY"):
434 fp.addProperty(
"App::PropertyFloatList",
"TranslationY",
436 "Object translation along global Y direction.")
437 if not hasattr(fp,
"TranslationZ"):
438 fp.addProperty(
"App::PropertyFloatList",
"TranslationZ",
440 "Object translation along global Z direction.")
442 if not hasattr(fp,
"RotationPointX"):
443 fp.addProperty(
"App::PropertyFloatList",
"RotationPointX",
445 "Object rotation point X coordinate.")
446 if not hasattr(fp,
"RotationPointY"):
447 fp.addProperty(
"App::PropertyFloatList",
"RotationPointY",
449 "Object rotation point Y coordinate.")
450 if not hasattr(fp,
"RotationPointZ"):
451 fp.addProperty(
"App::PropertyFloatList",
"RotationPointZ",
453 "Object rotation point Z coordinate.")
455 if not hasattr(fp,
"RotationAxisX"):
456 fp.addProperty(
"App::PropertyFloatList",
"RotationAxisX",
457 "Trajectory",
"Object rotation axis component X.")
458 if not hasattr(fp,
"RotationAxisY"):
459 fp.addProperty(
"App::PropertyFloatList",
"RotationAxisY",
460 "Trajectory",
"Object rotation axis component Y.")
461 if not hasattr(fp,
"RotationAxisZ"):
462 fp.addProperty(
"App::PropertyFloatList",
"RotationAxisZ",
463 "Trajectory",
"Object rotation axis component Z.")
464 if not hasattr(fp,
"RotationAngle"):
465 fp.addProperty(
"App::PropertyFloatList",
"RotationAngle",
467 "Rotation angle in degrees.")
470 if not hasattr(fp,
"ShowFrame"):
471 fp.addProperty(
"App::PropertyBool",
"ShowFrame",
"Frame",
472 "Show a frame for current pose." 474 if not hasattr(fp,
"FrameTransparency"):
475 fp.addProperty(
"App::PropertyPercent",
"FrameTransparency",
476 "Frame",
"Transparency of the frame in percents." 477 ).FrameTransparency = 0
478 if not hasattr(fp,
"ShowFrameArrowheads"):
479 fp.addProperty(
"App::PropertyBool",
"ShowFrameArrowheads",
"Frame",
480 "Show arrowheads for frame axis arrow's." 481 ).ShowFrameArrowheads =
True 482 if not hasattr(fp,
"FrameArrowheadLength"):
483 fp.addProperty(
"App::PropertyFloatConstraint",
484 "FrameArrowheadLength",
"Frame",
485 "Frame axis arrow's arrowhead length.\n" 486 +
"Range is < 1.0 | 1e6 >." 487 ).FrameArrowheadLength = (10, 1.0, 1e6, 1)
489 fp.FrameArrowheadLength = (fp.FrameArrowheadLength, 1.0, 1e6, 1)
490 if not hasattr(fp,
"FrameArrowheadRadius"):
491 fp.addProperty(
"App::PropertyFloatConstraint",
492 "FrameArrowheadRadius",
"Frame",
493 "Frame axis arrow's arrowhead bottom radius.\n" 494 +
"Range is < 0.5 | 1e6 >." 495 ).FrameArrowheadRadius = (5, 0.5, 1e6, 0.5)
497 fp.FrameArrowheadRadius = (fp.FrameArrowheadRadius, 0.5, 1e6, 0.5)
498 if not hasattr(fp,
"ShaftLength"):
499 fp.addProperty(
"App::PropertyFloatConstraint",
"ShaftLength",
500 "Frame",
"Frame axis arrow's shaft length.\n" 501 +
"Range is < 1.0 | 1e6 >." 502 ).ShaftLength = (20, 1.0, 1e6, 1)
504 fp.ShaftLength = (fp.ShaftLength, 1.0, 1e6, 1)
505 if not hasattr(fp,
"ShaftWidth"):
506 fp.addProperty(
"App::PropertyFloatConstraint",
"ShaftWidth",
507 "Frame",
"Frame axis arrow's shaft width.\n" 508 +
"Range is < 1.0 | 64 >." 509 ).ShaftWidth = (4, 1.0, 64, 1)
511 fp.ShaftWidth = (fp.ShaftWidth, 1.0, 64, 1)
512 if not hasattr(fp,
"ShowFrameLabels"):
513 fp.addProperty(
"App::PropertyBool",
"ShowFrameLabels",
514 "Frame",
"Show label for frame axes." 515 ).ShowFrameLabels =
True 518 if not hasattr(fp,
"ShowRotationAxis"):
519 fp.addProperty(
"App::PropertyBool",
"ShowRotationAxis",
521 "Show currently used rotation axis." 522 ).ShowRotationAxis =
True 523 if not hasattr(fp,
"AxisLength"):
524 fp.addProperty(
"App::PropertyFloatConstraint",
"AxisLength",
525 "RotationAxis",
"The rotation axis length.\n" 526 +
"Range is < 1.0 | 1e6 >." 527 ).AxisLength = (20, 1.0, 1e6, 1)
529 fp.AxisLength = (fp.AxisLength, 1.0, 1e6, 1)
530 if not hasattr(fp,
"AxisWidth"):
531 fp.addProperty(
"App::PropertyFloatConstraint",
"AxisWidth",
532 "RotationAxis",
"The rotation axis width.\n" 533 +
"Range is < 1.0 | 64 >." 534 ).AxisWidth = (4, 1.0, 64, 1)
536 fp.AxisWidth = (fp.AxisWidth, 1.0, 64, 1)
537 if not hasattr(fp,
"AxisColor"):
538 fp.addProperty(
"App::PropertyColor",
"AxisColor",
539 "RotationAxis",
"The rotation axis width." 540 ).AxisColor = (1.000, 0.667, 0.000)
541 if not hasattr(fp,
"AxisTransparency"):
542 fp.addProperty(
"App::PropertyPercent",
"AxisTransparency",
544 "Transparency of the rotation axis in percents." 545 ).AxisTransparency = 0
546 if not hasattr(fp,
"ShowAxisArrowhead"):
547 fp.addProperty(
"App::PropertyBool",
"ShowAxisArrowhead",
548 "RotationAxis",
"Show arrowhead for axis arrow." 549 ).ShowAxisArrowhead =
True 550 if not hasattr(fp,
"AxisArrowheadLength"):
551 fp.addProperty(
"App::PropertyFloatConstraint",
552 "AxisArrowheadLength",
"RotationAxis",
553 "Frame axis arrow's arrowhead length.\n" 554 +
"Range is < 1.0 | 1e6 >." 555 ).AxisArrowheadLength = (10, 1.0, 1e6, 1)
557 fp.AxisArrowheadLength = (fp.AxisArrowheadLength, 1.0, 1e6, 1)
558 if not hasattr(fp,
"AxisArrowheadRadius"):
559 fp.addProperty(
"App::PropertyFloatConstraint",
560 "AxisArrowheadRadius",
"RotationAxis",
561 "Frame axis arrow's arrowhead bottom radius.\n" 562 +
"Range is < 0.5 | 1e6 >." 563 ).AxisArrowheadRadius = (5, 0.5, 1e6, 0.5)
565 fp.AxisArrowheadRadius = (fp.AxisArrowheadRadius, 0.5, 1e6, 0.5)
566 if not hasattr(fp,
"ShowAxisLabel"):
567 fp.addProperty(
"App::PropertyBool",
"ShowAxisLabel",
568 "RotationAxis",
"Show label for rotation axis." 569 ).ShowAxisLabel =
True 572 if not hasattr(fp,
"FontSize"):
573 fp.addProperty(
"App::PropertyIntegerConstraint",
"FontSize",
574 "Labels",
"Label font size.\n" 575 +
"Range is < 1 | 100 >." 576 ).FontSize = (10, 1, 100, 1)
578 fp.FontSize = (fp.FontSize, 1, 100, 1)
579 if not hasattr(fp,
"DistanceToAxis"):
580 fp.addProperty(
"App::PropertyFloatConstraint",
"DistanceToAxis",
581 "Labels",
"Distance from label to its axis.\n" 582 +
"Range is < 0.5 | 1e6 >." 583 ).DistanceToAxis = (5, 0.5, 1e6, 0.5)
585 fp.DistanceToAxis = (fp.DistanceToAxis, 0.5, 1e6, 0.5)
586 if not hasattr(fp,
"Subscription"):
587 fp.addProperty(
"App::PropertyString",
"Subscription",
"Labels",
588 "Subscription added to an axis name." 590 if not hasattr(fp,
"Superscription"):
591 fp.addProperty(
"App::PropertyString",
"Superscription",
"Labels",
592 "Superscription added to an axis name." 593 ).Superscription =
"" 594 if not hasattr(fp,
"FontFamily"):
595 fp.addProperty(
"App::PropertyEnumeration",
"FontFamily",
596 "Labels",
"Label font family." 597 ).FontFamily = [
"SERIF",
"SANS",
"TYPEWRITER"]
598 if not hasattr(fp,
"FontStyle"):
599 fp.addProperty(
"App::PropertyEnumeration",
"FontStyle",
600 "Labels",
"Label font style." 601 ).FontStyle = [
"NONE",
"BOLD",
"ITALIC",
605 if not hasattr(fp,
"Placement"):
606 fp.addProperty(
"App::PropertyPlacement",
"Placement",
"Base",
607 "Current placement for animated objects in " 611 fp.setEditorMode(
"ObjectPlacement", 1)
612 fp.setEditorMode(
"ParentFramePlacement", 1)
615 fp.setEditorMode(
"Placement", 2)
616 fp.setEditorMode(
"ValidTrajectory", 2)
618 import AnimateDocumentObserver
634 fp.RotationAngle = traj[
"RotationAngle"]
635 fp.RotationAxisX = traj[
"RotationAxisX"]
636 fp.RotationAxisY = traj[
"RotationAxisY"]
637 fp.RotationAxisZ = traj[
"RotationAxisZ"]
638 fp.RotationPointX = traj[
"RotationPointX"]
639 fp.RotationPointY = traj[
"RotationPointY"]
640 fp.RotationPointZ = traj[
"RotationPointZ"]
641 fp.TranslationX = traj[
"TranslationX"]
642 fp.TranslationY = traj[
"TranslationY"]
643 fp.TranslationZ = traj[
"TranslationZ"]
644 fp.Timestamps = traj[
"Timestamps"]
646 FreeCAD.Console.PrintError(
"Invalid trajectory!")
662 return prop
in [
"Timestamps",
"TranslationX",
"TranslationY",
663 "TranslationZ",
"RotationPointX",
"RotationPointY",
664 "RotationPointZ",
"RotationAxisX",
"RotationAxisY",
665 "RotationAxisZ",
"RotationAngle"]
694 translation_y=[], translation_z=[],
695 rotation_point_x=[], rotation_point_y=[],
696 rotation_point_z=[], rotation_axis_x=[],
697 rotation_axis_y=[], rotation_axis_z=[],
698 rotation_angle=[], trajectory=None):
700 if trajectory
is not None and isinstance(trajectory, dict):
701 for key
in [
"Timestamps",
"TranslationX",
"TranslationY",
702 "TranslationZ",
"RotationPointX",
"RotationPointY",
703 "RotationPointZ",
"RotationAxisX",
"RotationAxisY",
704 "RotationAxisZ",
"RotationAngle"]:
705 if key
not in trajectory.keys():
706 FreeCAD.Console.PrintWarning(
"Trajectory misses key " +
709 timestamps = trajectory[
"Timestamps"]
710 translation_x = trajectory[
"TranslationX"]
711 translation_y = trajectory[
"TranslationY"]
712 translation_z = trajectory[
"TranslationZ"]
713 rotation_point_x = trajectory[
"RotationPointX"]
714 rotation_point_y = trajectory[
"RotationPointY"]
715 rotation_point_z = trajectory[
"RotationPointZ"]
716 rotation_axis_x = trajectory[
"RotationAxisX"]
717 rotation_axis_y = trajectory[
"RotationAxisY"]
718 rotation_axis_z = trajectory[
"RotationAxisZ"]
719 rotation_angle = trajectory[
"RotationAngle"]
722 if len(timestamps) == 0
or \
723 (len(timestamps) != 0
and 724 (len(timestamps) != len(timestamps)
or 725 len(timestamps) != len(translation_x)
or 726 len(timestamps) != len(translation_y)
or 727 len(timestamps) != len(translation_z)
or 728 len(timestamps) != len(rotation_point_x)
or 729 len(timestamps) != len(rotation_point_y)
or 730 len(timestamps) != len(rotation_point_z)
or 731 len(timestamps) != len(rotation_axis_x)
or 732 len(timestamps) != len(rotation_axis_y)
or 733 len(timestamps) != len(rotation_axis_z)
or 734 len(timestamps) != len(rotation_angle))):
735 FreeCAD.Console.PrintWarning(
"Trajectory has lists with " 736 +
"inconsistent or zero " 741 if any([timestamps[i] >= timestamps[i+1]
742 for i
in range(len(timestamps)-1)]):
743 FreeCAD.Console.PrintWarning(
"Trajectory 'Timestamps' is not " 744 +
"list of increasing values.\n")
747 if any([sum([rotation_axis_x[i]**2,
748 rotation_axis_y[i]**2,
749 rotation_axis_z[i]**2]) != 1
750 for i
in range(len(rotation_axis_x))]):
751 FreeCAD.Console.PrintWarning(
"Trajectory 'Rotation Axis' " 752 +
"elements don't have norm 1.\n")
780 if fp.Time <= fp.Timestamps[0]:
785 elif fp.Time >= fp.Timestamps[-1]:
792 indices = [bisect(fp.Timestamps, fp.Time)]
794 indices.insert(0, indices[0]-1)
795 weights = [fp.Timestamps[indices[1]] - fp.Time,
796 fp.Time - fp.Timestamps[indices[0]]]
797 if not fp.Interpolate:
798 if weights[0] > weights[1]:
803 weights = [weights[0]/sum(weights), weights[1]/sum(weights)]
805 return indices, weights
941 axis.insertChild(self.
font, 1)
947 frame.insertChild(self.
font, 1)
949 self.
frame.addChild(frame)
957 vp.Object.Proxy.setProperties(vp.Object)
974 if prop ==
"Placement" and hasattr(fp,
"Placement"):
975 trans = fp.Placement.Base
976 rot = fp.Placement.Rotation
980 if len(fp.Proxy.pose[
"rot_point"]) == 3
and \
981 len(fp.Proxy.pose[
"rot_axis"]) == 3:
983 coin.SbRotation(coin.SbVec3f(0, 1, 0),
984 coin.SbVec3f(fp.Proxy.pose[
"rot_axis"][0],
985 fp.Proxy.pose[
"rot_axis"][1],
986 fp.Proxy.pose[
"rot_axis"][2])
989 (fp.Proxy.pose[
"rot_point"][0],
990 fp.Proxy.pose[
"rot_point"][1],
991 fp.Proxy.pose[
"rot_point"][2]))
994 elif prop ==
"ShowFrame" and hasattr(fp,
"ShowFrame"):
996 self.
frame.whichChild.setValue(coin.SO_SWITCH_ALL)
998 self.
frame.whichChild.setValue(coin.SO_SWITCH_NONE)
1000 elif prop ==
"FrameTransparency" and hasattr(fp,
"FrameTransparency"):
1002 setValue(0xff0000ff - (0xff*fp.FrameTransparency)//100)
1004 setValue(0x00ff00ff - (0xff*fp.FrameTransparency)//100)
1006 setValue(0x0000ffff - (0xff*fp.FrameTransparency)//100)
1008 elif prop ==
"ShaftLength" and hasattr(fp,
"ShaftLength"):
1009 self.
frame_shaft.vertexProperty.getValue().vertex.\
1010 set1Value(1, 0, fp.ShaftLength, 0)
1011 if hasattr(fp,
"FrameArrowheadLength"):
1013 0, fp.ShaftLength + fp.FrameArrowheadLength/2, 0)
1014 if not fp.ShowFrameArrowheads
and hasattr(fp,
"DistanceToAxis"):
1016 0, fp.ShaftLength + fp.DistanceToAxis, 0)
1018 elif prop ==
"FrameArrowheadLength" and \
1019 hasattr(fp,
"FrameArrowheadLength"):
1021 if hasattr(fp,
"ShaftLength"):
1023 0, fp.ShaftLength + fp.FrameArrowheadLength/2, 0)
1024 if fp.ShowFrameArrowheads
and hasattr(fp,
"DistanceToAxis"):
1026 0, fp.FrameArrowheadLength/2 + fp.DistanceToAxis, 0)
1028 elif prop ==
"ShaftWidth" and hasattr(fp,
"ShaftWidth"):
1031 elif prop ==
"FrameArrowheadRadius" and \
1032 hasattr(fp,
"FrameArrowheadRadius"):
1034 fp.FrameArrowheadRadius)
1036 elif prop ==
"ShowFrameArrowheads" and \
1037 hasattr(fp,
"ShowFrameArrowheads"):
1038 if fp.ShowFrameArrowheads:
1040 if hasattr(fp,
"FrameArrowheadLength")
and \
1041 hasattr(fp,
"DistanceToAxis"):
1043 0, fp.FrameArrowheadLength/2 + fp.DistanceToAxis, 0)
1046 if hasattr(fp,
"ShaftLength")
and \
1047 hasattr(fp,
"DistanceToAxis"):
1049 0, fp.ShaftLength + fp.DistanceToAxis, 0)
1051 elif prop ==
"ShowFrameLabels" and hasattr(fp,
"ShowFrameLabels"):
1052 for label
in self.
labels[:3]:
1053 if fp.ShowFrameLabels:
1054 label.whichChild.setValue(coin.SO_SWITCH_ALL)
1056 label.whichChild.setValue(coin.SO_SWITCH_NONE)
1059 elif prop ==
"ShowRotationAxis" and hasattr(fp,
"ShowRotationAxis"):
1060 if fp.ShowRotationAxis:
1061 self.
rot_axis.whichChild.setValue(coin.SO_SWITCH_ALL)
1063 self.
rot_axis.whichChild.setValue(coin.SO_SWITCH_NONE)
1065 elif prop ==
"AxisTransparency" and \
1066 (hasattr(fp,
"AxisColor")
and hasattr(fp,
"AxisTransparency")):
1068 (round(0xff*fp.AxisColor[0]) << 24)
1069 + (round(0xff*fp.AxisColor[1]) << 16)
1070 + (round(0xff*fp.AxisColor[2]) << 8)
1071 + 0xff*(100 - fp.AxisTransparency)//100)
1073 elif prop ==
"AxisColor" and \
1074 (hasattr(fp,
"AxisColor")
and hasattr(fp,
"AxisTransparency")):
1076 (round(0xff*fp.AxisColor[0]) << 24)
1077 + (round(0xff*fp.AxisColor[1]) << 16)
1078 + (round(0xff*fp.AxisColor[2]) << 8)
1079 + 0xff*(100 - fp.AxisTransparency)//100)
1084 elif prop ==
"AxisWidth" and hasattr(fp,
"AxisWidth"):
1087 elif prop ==
"AxisLength" and hasattr(fp,
"AxisLength"):
1089 set1Value(1, 0, fp.AxisLength, 0)
1090 if hasattr(fp,
"AxisArrowheadLength"):
1092 0, fp.AxisLength + fp.AxisArrowheadLength/2, 0)
1093 if not fp.ShowAxisArrowhead
and hasattr(fp,
"DistanceToAxis"):
1095 0, fp.AxisLength + fp.DistanceToAxis, 0)
1097 elif prop ==
"AxisArrowheadLength" and \
1098 hasattr(fp,
"AxisArrowheadLength"):
1100 fp.AxisArrowheadLength)
1101 if hasattr(fp,
"AxisLength"):
1103 0, fp.AxisLength + fp.AxisArrowheadLength/2, 0)
1104 if fp.ShowAxisArrowhead
and hasattr(fp,
"DistanceToAxis"):
1106 0, fp.AxisArrowheadLength/2 + fp.DistanceToAxis, 0)
1108 elif prop ==
"AxisArrowheadRadius" and \
1109 hasattr(fp,
"AxisArrowheadRadius"):
1111 fp.AxisArrowheadRadius)
1113 elif prop ==
"ShowAxisArrowhead" and hasattr(fp,
"ShowAxisArrowhead"):
1114 if fp.ShowAxisArrowhead:
1117 if hasattr(fp,
"AxisArrowheadLength")
and \
1118 hasattr(fp,
"DistanceToAxis"):
1120 0, fp.AxisArrowheadLength/2 + fp.DistanceToAxis, 0)
1123 coin.SO_SWITCH_NONE)
1124 if hasattr(fp,
"AxisLength")
and hasattr(fp,
"DistanceToAxis"):
1126 0, fp.AxisLength + fp.DistanceToAxis, 0)
1128 elif prop ==
"ShowAxisLabel" and hasattr(fp,
"ShowAxisLabel"):
1129 if fp.ShowAxisLabel:
1130 self.
labels[-1].whichChild.setValue(coin.SO_SWITCH_ALL)
1132 self.
labels[-1].whichChild.setValue(coin.SO_SWITCH_NONE)
1135 elif prop ==
"Subscription" and hasattr(fp,
"Subscription"):
1137 l.string.setValues(2, 1, [fp.Subscription])
1139 elif prop ==
"Superscription" and hasattr(fp,
"Superscription"):
1141 l.string.setValues(0, 1, [fp.Superscription])
1143 elif prop ==
"FontFamily" and hasattr(fp,
"FontFamily"):
1144 if fp.FontFamily ==
"SERIF":
1145 self.
font.family.setValue(self.
font.SERIF)
1146 if fp.FontFamily ==
"SANS":
1147 self.
font.family.setValue(self.
font.SANS)
1148 if fp.FontFamily ==
"TYPEWRITER":
1149 self.
font.family.setValue(self.
font.TYPEWRITER)
1151 elif prop ==
"FontStyle" and hasattr(fp,
"FontStyle"):
1152 if fp.FontStyle ==
"NONE":
1153 self.
font.style.setValue(self.
font.NONE)
1154 if fp.FontStyle ==
"BOLD":
1155 self.
font.style.setValue(self.
font.BOLD)
1156 if fp.FontStyle ==
"ITALIC":
1157 self.
font.style.setValue(self.
font.ITALIC)
1158 if fp.FontStyle ==
"BOLD ITALIC":
1159 self.
font.style.setValue(self.
font.BOLD | self.
font.ITALIC)
1161 elif prop ==
"FontSize" and hasattr(fp,
"FontSize"):
1162 self.
font.size.setValue(fp.FontSize)
1164 elif prop ==
"DistanceToAxis" and hasattr(fp,
"DistanceToAxis")
and \
1165 hasattr(fp,
"ShowFrameArrowheads")
and \
1166 hasattr(fp,
"ShowAxisArrowhead"):
1167 if fp.ShowFrameArrowheads
and hasattr(fp,
"FrameArrowheadLength"):
1169 0, fp.FrameArrowheadLength/2 + fp.DistanceToAxis, 0)
1170 elif hasattr(fp,
"ShaftLength"):
1172 0, fp.ShaftLength + fp.DistanceToAxis, 0)
1173 if fp.ShowAxisArrowhead
and hasattr(fp,
"AxisArrowheadLength"):
1175 0, fp.AxisArrowheadLength/2 + fp.DistanceToAxis, 0)
1176 elif hasattr(fp,
"AxisLength"):
1178 0, fp.AxisLength + fp.DistanceToAxis, 0)
1191 if prop ==
"Visibility":
1207 if hasattr(self,
"fp")
and self.
fp:
1208 return self.
fp.Group
1221 if hasattr(obj,
"Proxy")
and \
1222 isinstance(obj.Proxy, self.
fp.Proxy.__class__):
1235 return path.join(PATH_TO_ICONS,
"Trajectory.png")
1273 vp.setEditorMode(
"DisplayMode", 2)
1290 FreeCADGui.Control.showTaskView()
1295 if not vp.Object.ValidTrajectory:
1296 QMessageBox.warning(
1298 'Error while opening trajectory panel',
1299 "Valid trajectory is necessary to open " 1300 +
"a trajectory panel.")
1304 new_form = [FreeCADGui.PySideUic.loadUi(path.join(PATH_TO_UI,
1305 "AnimationTrajectory.ui"))]
1306 new_form[0].setWindowTitle(vp.Object.Label)
1311 FreeCADGui.Control.showDialog(self.
panel)
1312 except RuntimeError
as e:
1319 for obj
in FreeCAD.ActiveDocument.Objects:
1320 if hasattr(obj,
"Proxy")
and \
1321 obj.Proxy.__class__.__name__ ==
"TrajectoryProxy":
1322 if obj.ViewObject.Proxy.panel
is not None:
1323 trajectories.append(obj)
1325 if len(trajectories) > 0:
1327 trajectories[0].ViewObject.Proxy.panel.reject()
1332 for trajectory
in trajectories:
1333 form = FreeCADGui.PySideUic.loadUi(
1334 path.join(PATH_TO_UI,
1335 "AnimationTrajectory.ui"))
1336 form.setWindowTitle(trajectory.Label)
1340 forms.append(new_form[0])
1343 trajectories.append(vp.Object)
1348 for trajectory
in trajectories:
1349 trajectory.ViewObject.Proxy.panel = self.
panel 1350 FreeCADGui.Control.showDialog(self.
panel)
1355 QMessageBox.warning(
1357 'Error while opening trajectory panel',
1358 "A different panel is already active.\n" 1359 +
"Close it before opening this one.")
1360 FreeCADGui.Control.showTaskView()
1376 action = menu.addAction(
"Select Time")
1390 label_strings = [
"X",
"Y",
"Z",
"O"]
1391 colors = [0xFF0000FF, 0x00FF00FF, 0x0000FFFF]
1400 label_group = coin.SoSeparator()
1403 frame_axis_color = coin.SoPackedColor()
1404 frame_axis_color.orderedRGBA.setValue(colors[i])
1405 label_group.addChild(frame_axis_color)
1412 0, 3, [
"", label_strings[i],
""])
1417 self.
labels.append(coin.SoSwitch())
1418 self.
labels[i].addChild(label_group)
1434 shaft_vertices = coin.SoVertexProperty()
1435 shaft_vertices.vertex.setNum(2)
1436 shaft_vertices.vertex.set1Value(0, 0, 0, 0)
1438 self.
frame_shaft.vertexProperty.setValue(shaft_vertices)
1452 rot_y2x = coin.SoRotation()
1453 rot_y2x.rotation.setValue(coin.SbRotation(coin.SbVec3f(0, 1, 0),
1454 coin.SbVec3f(1, 0, 0)))
1455 rot_y2z = coin.SoRotation()
1456 rot_y2z.rotation.setValue(coin.SbRotation(coin.SbVec3f(0, 1, 0),
1457 coin.SbVec3f(0, 0, 1)))
1465 x_arrow = coin.SoSeparator()
1466 x_arrow.addChild(rot_y2x)
1470 x_arrow.addChild(frame_labels[0])
1471 y_arrow = coin.SoSeparator()
1475 y_arrow.addChild(frame_labels[1])
1476 z_arrow = coin.SoSeparator()
1477 z_arrow.addChild(rot_y2z)
1481 z_arrow.addChild(frame_labels[2])
1487 separated_frame = coin.SoSeparator()
1489 separated_frame.addChild(x_arrow)
1490 separated_frame.addChild(y_arrow)
1491 separated_frame.addChild(z_arrow)
1493 return separated_frame
1507 shaft_vertices = coin.SoVertexProperty()
1508 shaft_vertices.vertex.setNum(2)
1509 shaft_vertices.vertex.set1Value(0, 0, 0, 0)
1534 separated_axis = coin.SoSeparator()
1540 separated_axis.addChild(axis_label)
1542 return separated_axis
1563 return {
'Pixmap': path.join(PATH_TO_ICONS,
"TrajectoryCmd.png"),
1564 'MenuText':
"Trajectory",
1565 'ToolTip':
"Create Trajectory instance."}
1576 doc = FreeCAD.ActiveDocument
1577 a = doc.addObject(
"App::DocumentObjectGroupPython",
"Trajectory")
1595 if FreeCAD.ActiveDocument
is None:
panel
A TrajectoryPanel if one is active or None.
def isAllowedAlterView(self)
Method to tell FreeCAD if dialog is allowed to alter a view.
def __setstate__(self, state)
Necessary method to avoid errors when trying to restore unserializable objects.
axis_label_color
A SoPackedColor coloring a rotational axis(RA) label.
previous_times
A list of trajectory times before opening a panel.
def Activated(self)
Method used as a callback when the toolbar button or the menu item is clicked.
def isAllowedAlterDocument(self)
Method to tell FreeCAD if dialog is allowed to alter a document.
Class specifying Animate workbench's Trajectory button/command.
frame_shaft
A SoLineSet shaft for frame axes.
tf_y2axis
A SoTransform transformation from Y axis to a rotation axis.
def onChanged(self, fp, prop)
Method called after DocumentObjectGroupPython Trajectory was changed.
def addObserver()
Adds an AnimateDocumentObserver between FreeCAD's document observers safely.
rot_axis_arrowhead_cone
A SoCone arrowhead cone for a rotation axis.
def setProperties(self, vp)
Method to hide unused properties.
def __getstate__(self)
Necessary method to avoid errors when trying to save unserializable objects.
def isAllowedAlterSelection(self)
Method to tell FreeCAD if dialog is allowed to alter a selection.
rot_axis_color
A SoPackedColor coloring a rotational axis.
rot_axis
A SoSwitch with a rotation axis in form of an arrow.
frame_color_z
A SoPackedColor blue color for an Z axis.
def __init__(self, vp)
Initialization method for ViewProviderTrajectoryProxy.
def doubleClicked(self, vp)
Method called by FreeCAD when Trajectory is double-clicked in the Tree View.
def getIcon(self)
Method called by FreeCAD to supply an icon for the Tree View.
tf_object2world
A SoTransform transformation from object to world frame.
frame_arrowhead_translation
A SoTranslation moving frame arrowheads.
Proxy class for a DocumentObjectGroupPython Trajectory instance.
frame_color_y
A SoPackedColor green color for an Y axis.
frame_arrowhead_cone
A SoCone arrowhead cone for frame axes.
def onChanged(self, vp, prop)
Method called after Trajectory.ViewObject was changed.
def updateData(self, fp, prop)
Method called after DocumentObjectGroupPython Trajectory was changed.
label_translations
A list of SoTranslations moving labels.
def IsActive(self)
Method to specify when the toolbar button and the menu item are enabled.
label_texts
A list of SoText2s labels denoting all axes and an origin.
frame_color_x
A SoPackedColor red color for an X axis.
def makeFrame(self, frame_labels)
Method which makes a Coin3D frame to show a current pose in a trajectory.
def GetResources(self)
Method used by FreeCAD to retrieve resources to use for this command.
rot_axis_arrowhead
A SoSwitch translated cone for a rotation axis.
font
A SoFontStyle font for axes labels.
def __init__(self, fp)
Initialization method for TrajectoryProxy.
def change_trajectory(self, fp, traj)
Method used to change a Trajectory's trajectory.
def sliderChanged(self, value, form, trajectory)
Feedback method called when any slider position is changed.
visualisations
A SoSwitch with all visualisations (frame & rotation axis).
rot_axis_arrowhead_translation
A SoTranslation moving a RA arrowhead.
def setProperties(self, fp)
Method to set properties during initialization or document restoration.
Class providing funcionality to a Trajectory panel inside the TaskView.
def is_ValidTrajectory(self, timestamps=[], translation_x=[], translation_y=[], translation_z=[], rotation_point_x=[], rotation_point_y=[], rotation_point_z=[], rotation_axis_x=[], rotation_axis_y=[], rotation_axis_z=[], rotation_angle=[], trajectory=None)
Method to check if a trajectory is valid.
def getStandardButtons(self, *args)
Method to set just one button (close) to close the dialog.
def accept(self)
Feedback method called when 'OK' button was pressed to close the panel.
def reject(self)
Feedback method called when 'Cancel' button was pressed to close the panel.
rot_axis_drawstyle
A SoDrawStyle controlling RA shaft line width.
def is_trajectory_property(self, prop)
Method to check that a property describes a trajectory.
labels
A list of SoSwitches containing colored translated labels.
def attach(self, vp)
Method called by FreeCAD after initialization to attach Coin3D constructs.
Proxy class for Gui.ViewProviderDocumentObject Trajectory.ViewObject.
def setupContextMenu(self, vp, menu)
Method called by the FreeCAD to customize a context menu for a Trajectory.
frame_arrowhead
A SoSwitch translated cone for frame axes.
frame_drawstyle
A SoDrawStyle controlling frame axes shaft line width.
def __init__(self, trajectories, forms)
Initialization method for TrajectoryPanel.
def find_timestamp_indices_and_weights(self, fp)
Method to find weighted timestamps indices corresponding to a given time.
def claimChildren(self)
Method called by FreeCAD to retrieve assigned children.
def execute(self, fp)
Method called when recomputing a DocumentObjectGroupPython.
rot_axis_shaft
A SoLineSet shaft for a rotation axis.
def close(self)
Method used to close TrajectoryPanel.
def makeRotationAxis(self, axis_label)
Method which makes a Coin3D rotation axis to show in the FreeCAD View.
frame
A SoSeparator with a coordinate frame made from 3 RGB arrows.
def makeLabels(self)
Method which makes Coin3D labels to be displayed in the FreeCAD View.
pose
A dict describing a pose - position, rotation axis, point and angle.
trajectories
A list of DocumentObjectGroupPython Trajectory instances.
def canDropObject(self, obj)
Method called by FreeCAD to ask if an object obj can be dropped into a Group.
form
A list of QDialog instances to show in the TaskView.
def onDocumentRestored(self, fp)
Method called when document is restored to make sure everything is as it was.