11import io as StringIO
22
33from ..shapes import Shape , Compound , TOLERANCE
4- from ..geom import BoundBox
4+ from ..geom import BoundBox , Vector
55
66
77from OCP .gp import gp_Ax2 , gp_Pnt , gp_Dir
2020 height="%(height)s"
2121
2222>
23- <g transform="scale (%(unitScale )s, -%(unitScale )s) translate (%(xTranslate )s,%(yTranslate )s)" stroke-width="%(strokeWidth)s" fill="none">
23+ <g transform="translate (%(xTranslate )s,%(yTranslate )s) scale (%(unitScale )s, -%(unitScale )s)" stroke-width="%(strokeWidth)s" fill="none">
2424 <!-- hidden lines -->
2525 <g stroke="rgb(%(hiddenColor)s)" fill="none" stroke-dasharray="%(strokeWidth)s,%(strokeWidth)s" >
2626%(hiddenContent)s
@@ -137,9 +137,11 @@ def getSVG(shape, opts=None):
137137 height: Document height of the resulting image.
138138 marginLeft: Inset margin from the left side of the document.
139139 marginTop: Inset margin from the top side of the document.
140+ viewHeight: Height in model units. Used to set scale.
140141 projectionDir: Direction the camera will view the shape from.
142+ up: Up direction. Default (0, 0, 1).
141143 showAxes: Whether or not to show the axes indicator, which will only be
142- visible when the projectionDir is also at the default.
144+ visible when the projectionDir is also at the default.
143145 strokeWidth: Width of the line that visible edges are drawn with.
144146 strokeColor: Color of the line that visible edges are drawn with.
145147 hiddenColor: Color of the line that hidden edges are drawn with.
@@ -152,7 +154,9 @@ def getSVG(shape, opts=None):
152154 "height" : 240 ,
153155 "marginLeft" : 200 ,
154156 "marginTop" : 20 ,
155- "projectionDir" : (- 1.75 , 1.1 , 5 ),
157+ "viewHeight" : None ,
158+ "projectionDir" : (1 , - 1 , 1 ),
159+ "up" : (0 , 0 , 1 ),
156160 "showAxes" : True ,
157161 "strokeWidth" : - 1.0 , # -1 = calculated based on unitScale
158162 "strokeColor" : (0 , 0 , 0 ), # RGB 0-255
@@ -170,6 +174,7 @@ def getSVG(shape, opts=None):
170174 height = float (d ["height" ])
171175 marginLeft = float (d ["marginLeft" ])
172176 marginTop = float (d ["marginTop" ])
177+ viewHeight = float (d ["viewHeight" ]) if d .get ("viewHeight" ) else None
173178 projectionDir = tuple (d ["projectionDir" ])
174179 showAxes = bool (d ["showAxes" ])
175180 strokeWidth = float (d ["strokeWidth" ])
@@ -180,7 +185,13 @@ def getSVG(shape, opts=None):
180185 hlr = HLRBRep_Algo ()
181186 hlr .Add (shape .wrapped )
182187
183- projector = HLRAlgo_Projector (gp_Ax2 (gp_Pnt (), gp_Dir (* projectionDir )))
188+ vx = Vector (d ["up" ]).cross (Vector (projectionDir ))
189+ if vx .Length < 1e-6 :
190+ projector = HLRAlgo_Projector (gp_Ax2 (gp_Pnt (), gp_Dir (* projectionDir )))
191+ else :
192+ projector = HLRAlgo_Projector (
193+ gp_Ax2 (gp_Pnt (), gp_Dir (* projectionDir ), gp_Dir (* vx .toTuple ()))
194+ )
184195
185196 hlr .Projector (projector )
186197 hlr .Update ()
@@ -227,13 +238,17 @@ def getSVG(shape, opts=None):
227238 bb = Compound .makeCompound (hidden + visible ).BoundingBox ()
228239
229240 # width pixels for x, height pixels for y
230- unitScale = min (width / bb .xlen * 0.75 , height / bb .ylen * 0.75 )
231-
232- # compute amount to translate-- move the top left into view
233- (xTranslate , yTranslate ) = (
234- (0 - bb .xmin ) + marginLeft / unitScale ,
235- (0 - bb .ymax ) - marginTop / unitScale ,
236- )
241+ if viewHeight is not None :
242+ unitScale = height / viewHeight
243+ xTranslate = width / 2
244+ yTranslate = height / 2
245+ else :
246+ unitScale = min ((width / bb .xlen * 0.75 , height / bb .ylen * 0.75 ))
247+ # compute amount to translate-- move the top left into view
248+ (xTranslate , yTranslate ) = (
249+ marginLeft - bb .xmin * unitScale ,
250+ marginTop + bb .ymax * unitScale ,
251+ )
237252
238253 # If the user did not specify a stroke width, calculate it based on the unit scale
239254 if strokeWidth == - 1.0 :
0 commit comments