FreeCAD-macros
118 строк · 3.7 Кб
1# -*- coding: utf-8 -*-
2
3###############################################
4#
5# SketcherClipView
6#
7# This macro creates a temporary cross section at the
8# sketch plane in order to 'look into' an object when you
9# want to create a feature on the inside (i.e. create a revolved
10# groove on the inner side of a tube).
11#
12# The macro creates a clipping plane at the sketch plane and
13# activates it. Running the macro again deletes the clipping plane.
14#
15# If you map the macro to F7 it behaves almost exactly like
16# in Autodesk Inventor, from which I got the inspiration.
17#
18# (c) Ricardo Beck
19#################################################
20
21__Name__ = 'Sketcher Clip View'
22__Comment__ = 'Creates a temporary clipping plane at the support plane of the sketch'
23__License__ = ''
24__Web__ = 'https://forum.freecadweb.org/viewtopic.php?t=26608'
25__Wiki__ = ''
26__Icon__ = 'SketcherClipView.svg'
27__Help__ = 'Launch while editing a sketch'
28__Author__ = 'Ricardo Beck, galou_breizh'
29__Version__ = '1.1.0'
30__Date__ = '2018-05-29'
31__Status__ = 'Beta'
32__Requires__ = 'FreeCAD >= v0.17'
33__Files__ = 'SketcherClipView.svg'
34
35from pivy import coin
36
37import freecad as fc
38import FreeCAD as app
39import FreeCADGui as gui
40from PySide import QtCore
41
42
43def in_edit_mode():
44"""Return True if the Sketcher is in edit mode
45
46This is done by checking whether ActiveSketch is defined and
47ActiveSketch.ViewObject.TempoVis is not None.
48"""
49in_edit_mode = False
50try:
51in_edit_mode = (ActiveSketch.ViewObject.TempoVis is not None)
52except NameError:
53pass
54return in_edit_mode
55
56
57def check_leave_edit():
58if not in_edit_mode():
59clean()
60
61
62def clean():
63if hasattr(fc, 'SketcherClipView_clip_plane'):
64gui.activeDocument().ActiveView.getSceneGraph().removeChild(fc.SketcherClipView_clip_plane)
65del fc.SketcherClipView_clip_plane
66del fc.SketcherClipView_timer
67
68
69def main():
70# Check if there is a temporary clipping plane from a previous run of the
71# macro.
72if hasattr(fc, 'SketcherClipView_clip_plane'):
73# Clipping plane found, remove from scenegraph and delete the object.
74clean()
75return
76
77if not in_edit_mode():
78return
79
80# No clipping plane found, create one at the sketch base.
81
82# Get the placement information of the active sketch.
83try:
84mat = ActiveSketch.getGlobalPlacement()
85except NameError:
86# ActiveSketch undefined (i.e. not in sketch editing mode).
87return
88point = mat.Base
89normal = mat.Rotation.multVec(app.Vector(0, 0, 1))
90
91# Create coin3d vectors of the sketch position.
92coin_normal_vector = coin.SbVec3f(normal.x, normal.y, normal.z)
93coin_normal_vector.negate()
94coin_base_point = coin.SbVec3f(point.x, point.y, point.z)
95
96# Offset of the clipping plane so the sketch elements (lines, etc) are not cut off.
97sketch_offset_factor = -0.02
98
99coin_normal_vector_normalized = coin.SbVec3f(coin_normal_vector)
100coin_normal_vector_normalized.normalize()
101
102# Offset the clipping plane base by a fraction of the (normalized) normal vector.
103coin_base_point += (coin_normal_vector_normalized * sketch_offset_factor)
104
105# Create the clipping plane at the calculated position.
106fc.SketcherClipView_clip_plane = coin.SoClipPlane()
107fc.SketcherClipView_clip_plane.plane.setValue(coin.SbPlane(coin_normal_vector,coin_base_point))
108gui.activeDocument().ActiveView.getSceneGraph().insertChild(fc.SketcherClipView_clip_plane, 0)
109
110# Switch clipping plane on.
111fc.SketcherClipView_clip_plane.on.setValue(True)
112
113fc.SketcherClipView_timer = QtCore.QTimer()
114fc.SketcherClipView_timer.timeout.connect(check_leave_edit)
115fc.SketcherClipView_timer.start(100) # Pool every 100 ms.
116
117if __name__ == '__main__':
118main()
119