2018-01-15 14:35:59 +01:00
import FreeCAD
import Part
2018-01-16 15:29:51 +01:00
import json # For exporting part infos
import os # for safer path handling
2018-01-15 14:35:59 +01:00
if FreeCAD . GuiUp :
import FreeCADGui
2018-01-16 14:38:16 +01:00
from PySide import QtGui
2018-01-15 14:35:59 +01:00
__title__ = " ARTools "
__author__ = " Mathias Hauan Arbo "
__workbenchname__ = " ARBench "
__version__ = " 0.1 "
__url__ = " https://github.com/mahaarbo/ARBench "
2018-01-16 14:38:16 +01:00
__doc__ = """
Useful tools for the Annotations for Robotics workbench . """
2018-01-15 14:35:59 +01:00
2018-01-16 14:38:16 +01:00
###################################################################
# Module functions
###################################################################
2018-01-15 14:35:59 +01:00
def vector2list ( vec , scale = 1e-3 ) :
""" Gives the vector as a list, set scale for scaling factor.
default scale = 1e-3 for units in m . """
return [ vec . x * scale , vec . y * scale , vec . z * scale ]
def matrix2list ( mat , scale = 1e-3 ) :
""" Gives the transformation matrix as a list, set scale 1 to get in mm. """
return [ [ mat . A11 , mat . A12 , mat . A13 , mat . A14 * scale ] ,
[ mat . A21 , mat . A22 , mat . A23 , mat . A24 * scale ] ,
[ mat . A31 , mat . A32 , mat . A33 , mat . A34 * scale ] ,
[ mat . A41 , mat . A42 , mat . A43 , mat . A44 ] ]
2022-02-22 20:45:54 +03:00
def placement2pose ( pl , scale = 1e-3 ) :
""" Gives the placement as an dictionary for geometry_msgs/Pose type. """
return { " position " : {
" x " : pl . Base . x * scale ,
" y " : pl . Base . y * scale ,
" z " : pl . Base . z * scale
} ,
" orientation " : {
" x " : pl . Rotation . Axis . x ,
" y " : pl . Rotation . Axis . y ,
" z " : pl . Rotation . Axis . z ,
" w " : pl . Rotation . Angle
}
}
2018-01-15 14:35:59 +01:00
2018-01-16 14:38:16 +01:00
def placement2axisvec ( pl , scale = 1e-3 ) :
2018-01-15 14:35:59 +01:00
""" Gives the placement as an dictionary of origin and rotation.
origin : [ x , y , z ] , rotation : { axis : [ ax , ay , az ] , angle : ang } """
2018-01-16 14:38:16 +01:00
return { " origin " : vector2list ( pl . Base , scale ) ,
2018-01-15 14:35:59 +01:00
" rotation " : { " axis " : vector2list ( pl . Rotation . Axis , scale = 1 ) ,
" angle " : pl . Rotation . Angle } }
2018-01-16 14:38:16 +01:00
def boundingBox2list ( bb , scale = 1e-3 ) :
""" Gives the bounding box as a list in m instead of mm """
return [ bb . XMin * scale , bb . XMax * scale ,
bb . YMin * scale , bb . YMax * scale ,
bb . ZMin * scale , bb . ZMax * scale ]
def principalProperties2dict ( pp , scale = 1e-3 ) :
npp = { }
2021-12-17 16:57:58 +03:00
for key , value in pp . items ( ) :
2018-01-16 14:38:16 +01:00
if type ( value ) is FreeCAD . Vector :
npp [ key . lower ( ) ] = vector2list ( value , scale = 1e-3 )
else :
npp [ key . lower ( ) ] = value
return npp
2018-01-15 14:35:59 +01:00
def describeSubObject ( subobj ) :
""" Returns PrimitiveType, ShapeType. """
if isinstance ( subobj , Part . Vertex ) :
return " Vertex " , " Vertex "
elif isinstance ( subobj , Part . Edge ) :
if isinstance ( subobj . Curve , Part . Arc ) :
return " Arc " , " Edge "
elif isinstance ( subobj . Curve , Part . ArcOfCircle ) :
return " ArcOfCircle " , " Edge "
elif isinstance ( subobj . Curve , Part . ArcOfEllipse ) :
return " ArcOfEllipse " , " Edge "
elif isinstance ( subobj . Curve , Part . ArcOfHyperbola ) :
return " ArcOfHyperbola " , " Edge "
elif isinstance ( subobj . Curve , Part . ArcOfParabola ) :
return " ArcOfParabola " , " Edge "
elif isinstance ( subobj . Curve , Part . BSplineCurve ) :
return " BSplineCurve " , " Edge "
elif isinstance ( subobj . Curve , Part . BezierCurve ) :
return " BezierCurve " , " Edge "
elif isinstance ( subobj . Curve , Part . Circle ) :
return " Circle " , " Edge "
elif isinstance ( subobj . Curve , Part . Ellipse ) :
return " Ellipse " , " Edge "
elif isinstance ( subobj . Curve , Part . Hyperbola ) :
return " Hyperbola " , " Edge "
elif isinstance ( subobj . Curve , Part . Line ) :
return " Line " , " Edge "
elif isinstance ( subobj . Curve , Part . Parabola ) :
return " Parabola " , " Edge "
else :
FreeCAD . Console . PrintError ( " Unknown edge type " )
elif isinstance ( subobj , Part . Face ) :
if isinstance ( subobj . Surface , Part . BSplineSurface ) :
return " BSplineSurface " , " Face "
elif isinstance ( subobj . Surface , Part . BezierSurface ) :
return " BezierSurface " , " Face "
elif isinstance ( subobj . Surface , Part . Cylinder ) :
return " Cylinder " , " Face "
elif isinstance ( subobj . Surface , Part . Plane ) :
return " Plane " , " Face "
elif isinstance ( subobj . Surface , Part . Sphere ) :
return " Sphere " , " Face "
elif isinstance ( subobj . Surface , Part . Toroid ) :
return " Toroid " , " Face "
elif isinstance ( subobj . Surface , Part . Cone ) :
return " Cone " , " Face "
else :
FreeCAD . Console . PrintError ( " Unknown surface type " )
# Better strategy desirable for the following:
elif isinstance ( subobj , Part . Wire ) :
return " Wire " , " Wire "
elif isinstance ( subobj , Part . Shell ) :
return " Shell " , " Shell "
elif isinstance ( subobj , Part . Solid ) :
return " Solid " , " Solid "
elif isinstance ( subobj , Part . Compsolid ) :
return " Compsolid " , " Compsolid "
elif isinstance ( subobj , Part . Compound ) :
return " Compound " , " Compound "
else :
FreeCAD . Console . PrintError ( " Unable to identify subobject. " )
def closeToZero ( a , tol = 1e-10 ) :
return abs ( a ) < tol
def spawnClassCommand ( classname , function , resources ) :
"""
Commands , or buttons , are tedious to write . So this function spawns
one if the function to be executed takes no arguments .
Example usage :
spawnClassCommand ( " testcommand " , testfunc ,
{ " Pixmap " : " " , " MenuText " : " menutext " , " ToolTip " : " tooltiptext " } )
2018-01-16 14:38:16 +01:00
then add " testcommand " to commandlist in InitGui . py
"""
2018-01-15 14:35:59 +01:00
def Activated ( s ) :
function ( )
def GetResources ( s ) :
return resources
CommandClass = type ( " classname " , ( object , ) , { " Activated " : Activated ,
" GetResources " : GetResources } )
FreeCADGui . addCommand ( classname , CommandClass ( ) )
2018-01-16 14:38:16 +01:00
def getLocalPartProps ( obj ) :
old_placement = obj . Placement
obj . Placement = FreeCAD . Placement ( )
# Part properties
partprops = {
" label " : obj . Label ,
2022-02-22 20:45:54 +03:00
" placement " : placement2pose ( old_placement ) ,
# "boundingbox": boundingBox2list(obj.Shape.BoundBox),
# "volume": obj.Shape.Volume*1e-9,
# "centerofmass": vector2list(obj.Shape.CenterOfMass),
# "principalproperties": principalProperties2dict(obj.Shape.PrincipalProperties)
2018-01-16 14:38:16 +01:00
}
obj . Placement = old_placement
return partprops
2022-02-22 20:45:54 +03:00
# if "IsMainPosition" in obj.PropertiesList:
def getGraspPoseProps ( obj ) :
# part = obj.PartToHandle
partprops = getLocalPartProps ( obj . PartToHandle )
grasppose = { obj . Container . Label : {
" placement " : placement2pose ( obj . Container . Placement ) ,
" distance " : obj . GripSize
# "OperationType" : obj.OperationType
# "Operation Priority" : obj.OperationPriority
# obj.Operation Parameter 1 : obj.OperationParameter1
# obj.Operation Parameter 2 : obj.OperationParameter2
# obj.Operation Parameter 3 : obj.OperationParameter3
}
}
graspposes = { " features " : { " grasp-poses " : grasppose } }
partprops . update ( graspposes )
opts = QtGui . QFileDialog . DontConfirmOverwrite
ofile , filt = QtGui . QFileDialog . getSaveFileName ( None , ' test ' ,
os . getenv ( " HOME " ) ,
" *.json " , options = opts )
odir , of = os . path . split ( ofile )
if not os . path . exists ( odir ) :
os . makedirs ( odir )
if not of . lower ( ) . endswith ( " .json " ) :
ofile = ofile + " .json "
with open ( ofile , " w " , encoding = " utf8 " ) as propfile :
json . dump ( partprops , propfile , indent = 1 , separators = ( ' , ' , ' : ' ) )
2018-01-16 14:38:16 +01:00
###################################################################
# Export functions
###################################################################
def exportPartInfo ( obj , ofile ) :
"""
Exports part info to a new json file .
The part info includes :
Placement relative to world frame , bounding box , volume , center of mass ,
principal properties .
For more information on principal properties , see TopoShape in OCCT
documentation .
"""
# File path stuff
odir , of = os . path . split ( ofile )
if not os . path . exists ( odir ) :
os . makedirs ( odir )
if not of . lower ( ) . endswith ( " .json " ) :
ofile = ofile + " .json "
partprops = getLocalPartProps ( obj )
2021-12-17 16:57:58 +03:00
with open ( ofile , " w " , encoding = " utf8 " ) as propfile :
2018-01-16 14:38:16 +01:00
json . dump ( partprops , propfile , indent = 1 , separators = ( ' , ' , ' : ' ) )
return True
def appendPartInfo ( obj , ofile ) :
""" Rewrites/appends part info to an existing json file.
The part info includes :
Placement relative to world frame , bounding box , volume , center of mass ,
principal properties .
For more information on principal properties , see TopoShape in OCCT
documentation .
"""
2021-12-17 16:57:58 +03:00
with open ( ofile , " r " , encoding = " utf8 " ) as propfile :
2018-01-16 14:38:16 +01:00
partprops = json . load ( propfile )
new_props = getLocalPartProps ( obj )
partprops . update ( new_props )
2021-12-17 16:57:58 +03:00
with open ( ofile , " w " , encoding = " utf8 " ) as propfile :
2018-01-16 14:38:16 +01:00
json . dump ( partprops , propfile , indent = 1 , separators = ( ' , ' , ' : ' ) )
return True
def exportFeatureFrames ( obj , ofile ) :
""" Exports feature frames attached to a part. """
# Get the feature frames
import ARFrames
2021-12-17 16:57:58 +03:00
ff_check = lambda x : isinstance ( x . Proxy , ARFrames . FeatureFrame ) if hasattr ( x , ' Proxy ' ) else False
2018-01-16 14:38:16 +01:00
ff_list = filter ( ff_check , obj . InList )
ff_named = { ff . Label : ff . Proxy . getDict ( ) for ff in ff_list }
feature_dict = { " features " : ff_named }
# File stuff
odir , of = os . path . split ( ofile )
if not os . path . exists ( odir ) :
os . makedirs ( odir )
if not of . lower ( ) . endswith ( " .json " ) :
ofile = ofile + " .json "
2021-12-17 16:57:58 +03:00
with open ( ofile , " w " , encoding = " utf8 " ) as propfile :
2018-01-16 15:29:51 +01:00
json . dump ( feature_dict , propfile , indent = 1 , separators = ( ' , ' , ' : ' ) )
2018-01-16 14:38:16 +01:00
return True
def appendFeatureFrames ( obj , ofile ) :
""" Rewrites/appends featureframes attached to a part to an existing json
file . """
# Get the feature frames
import ARFrames
2021-12-17 16:57:58 +03:00
with open ( ofile , " r " , encoding = " utf8 " ) as propfile :
2018-01-16 14:38:16 +01:00
partprops = json . load ( propfile )
2021-12-17 16:57:58 +03:00
ff_check = lambda x : isinstance ( x . Proxy , ARFrames . FeatureFrame ) if hasattr ( x , ' Proxy ' ) else False
2018-01-16 14:38:16 +01:00
ff_list = filter ( ff_check , obj . InList )
ff_named = { ff . Label : ff . Proxy . getDict ( ) for ff in ff_list }
feature_dict = { " features " : ff_named }
if " features " not in partprops . keys ( ) :
partprops . update ( feature_dict )
else :
partprops [ " features " ] . update ( feature_dict [ " features " ] )
2021-12-17 16:57:58 +03:00
with open ( ofile , " w " , encoding = " utf8 " ) as propfile :
2018-01-16 15:29:51 +01:00
json . dump ( partprops , propfile , indent = 1 , separators = ( ' , ' , ' : ' ) )
2018-01-16 14:38:16 +01:00
return True
def exportPartInfoDialogue ( ) :
""" Spawns a dialogue window for part info exporting """
# Select only true parts
s = FreeCADGui . Selection . getSelection ( )
FreeCADGui . Selection . clearSelection ( )
if len ( s ) == 0 :
FreeCAD . Console . PrintError ( " No part selected. " )
return False
unique_selected = [ ]
for item in s :
if item not in unique_selected and isinstance ( item , Part . Feature ) :
# Ensuring that we are parts
unique_selected . append ( item )
FreeCADGui . Selection . addSelection ( item )
# Fix wording
textprompt = " Save the properties of the part "
if len ( unique_selected ) > 1 :
textprompt = textprompt + " s "
opts = QtGui . QFileDialog . DontConfirmOverwrite
# Create file dialog
ofile , filt = QtGui . QFileDialog . getSaveFileName ( None , textprompt ,
2018-01-16 15:29:51 +01:00
os . getenv ( " HOME " ) ,
2018-01-16 14:38:16 +01:00
" *.json " , options = opts )
if ofile == " " :
# User cancelled
return False
if os . path . exists ( ofile ) :
msgbox = QtGui . QMessageBox ( )
msgbox . setText ( " File already exists. We can overwrite the file, or add the information/rewrite only relevant sections. " )
2021-12-17 16:57:58 +03:00
append_button = msgbox . addButton ( " Append " , QtGui . QMessageBox . YesRole )
overwrite_button = msgbox . addButton ( " Overwrite " , QtGui . QMessageBox . NoRole )
2018-01-16 14:38:16 +01:00
msgbox . exec_ ( )
if msgbox . clickedButton ( ) == append_button :
NEWFILE = False
elif msgbox . clickedButton ( ) == overwrite_button :
NEWFILE = True
else :
return False
else :
NEWFILE = True
if NEWFILE :
exportPartInfo ( unique_selected [ 0 ] , ofile )
else :
appendPartInfo ( unique_selected [ 0 ] , ofile )
if len ( unique_selected ) > 1 :
FreeCAD . Console . PrintWarning ( " Multi-part export not yet supported \n " )
FreeCAD . Console . PrintMessage ( " Properties exported to " + str ( ofile ) + " \n " )
def exportFeatureFramesDialogue ( ) :
""" Spawns a dialogue window for a part ' s feature frames to be exported. """
# Select only true parts
2021-12-17 16:57:58 +03:00
import ARFrames
2018-01-16 14:38:16 +01:00
s = FreeCADGui . Selection . getSelection ( )
FreeCADGui . Selection . clearSelection ( )
if len ( s ) == 0 :
FreeCAD . Console . PrintError ( " No part selected. " )
return False
unique_selected = [ ]
for item in s :
2021-12-17 16:57:58 +03:00
if item not in unique_selected and isinstance ( item . Proxy , ARFrames . FeatureFrame ) :
2018-01-16 14:38:16 +01:00
# Ensuring that we are parts
unique_selected . append ( item )
FreeCADGui . Selection . addSelection ( item )
# Fix wording
textprompt = " Save the feature frames attached to the part "
if len ( unique_selected ) > 1 :
textprompt = textprompt + " s "
opts = QtGui . QFileDialog . DontConfirmOverwrite
# Create file dialog
ofile , filt = QtGui . QFileDialog . getSaveFileName ( None , textprompt ,
2018-01-16 15:29:51 +01:00
os . getenv ( " HOME " ) ,
2018-01-16 14:38:16 +01:00
" *.json " , options = opts )
if ofile == " " :
# User cancelled
return False
if os . path . exists ( ofile ) :
msgbox = QtGui . QMessageBox ( )
msgbox . setText ( " File already exists. We can overwrite the file, or add the information/rewrite only relevant sections. " )
2021-12-17 16:57:58 +03:00
append_button = msgbox . addButton ( " Append " , QtGui . QMessageBox . YesRole )
overwrite_button = msgbox . addButton ( " Overwrite " , QtGui . QMessageBox . NoRole )
2018-01-16 14:38:16 +01:00
msgbox . exec_ ( )
if msgbox . clickedButton ( ) == append_button :
NEWFILE = False
elif msgbox . clickedButton ( ) == overwrite_button :
NEWFILE = True
else :
return False
else :
NEWFILE = True
if NEWFILE :
exportFeatureFrames ( unique_selected [ 0 ] , ofile )
else :
appendFeatureFrames ( unique_selected [ 0 ] , ofile )
if len ( unique_selected ) > 1 :
FreeCAD . Console . PrintWarning ( " Multi-part export not yet supported \n " )
2018-01-16 15:29:51 +01:00
FreeCAD . Console . PrintMessage ( " Feature frames of " + str ( unique_selected [ 0 ] . Label ) + " exported to " + str ( ofile ) + " \n " )
2018-01-16 14:38:16 +01:00
def exportPartInfoAndFeaturesDialogue ( ) :
""" Spawns a dialogue window for exporting both. """
2021-12-17 16:57:58 +03:00
import ARFrames
2018-01-16 14:38:16 +01:00
s = FreeCADGui . Selection . getSelection ( )
FreeCADGui . Selection . clearSelection ( )
if len ( s ) == 0 :
2021-12-17 16:57:58 +03:00
FreeCAD . Console . PrintError ( " No part selected " )
2018-01-16 14:38:16 +01:00
return False
unique_selected = [ ]
for item in s :
2021-12-17 16:57:58 +03:00
if item not in unique_selected :
2018-01-16 14:38:16 +01:00
# Ensuring that we are parts
unique_selected . append ( item )
FreeCADGui . Selection . addSelection ( item )
2021-12-17 16:57:58 +03:00
FreeCAD . Console . PrintMessage ( " Added for export " + str ( item . FullName ) + " \n " )
2018-01-16 14:38:16 +01:00
# Fix wording
textprompt = " Save the part info and feature frames attached to the part "
if len ( unique_selected ) > 1 :
textprompt = textprompt + " s "
opts = QtGui . QFileDialog . DontConfirmOverwrite
# Create file dialog
ofile , filt = QtGui . QFileDialog . getSaveFileName ( None , textprompt ,
2018-01-16 15:29:51 +01:00
os . getenv ( " HOME " ) ,
2018-01-16 14:38:16 +01:00
" *.json " , options = opts )
if ofile == " " :
# User cancelled
return False
if os . path . exists ( ofile ) :
msgbox = QtGui . QMessageBox ( )
msgbox . setText ( " File already exists. We can overwrite the file, or add the information/rewrite only relevant sections. " )
2021-12-17 16:57:58 +03:00
append_button = msgbox . addButton ( " Append " , QtGui . QMessageBox . YesRole )
overwrite_button = msgbox . addButton ( " Overwrite " , QtGui . QMessageBox . NoRole )
2018-01-16 14:38:16 +01:00
msgbox . exec_ ( )
if msgbox . clickedButton ( ) == append_button :
NEWFILE = False
elif msgbox . clickedButton ( ) == overwrite_button :
NEWFILE = True
else :
return False
else :
NEWFILE = True
if NEWFILE :
exportPartInfo ( unique_selected [ 0 ] , ofile )
appendFeatureFrames ( unique_selected [ 0 ] , ofile )
else :
appendPartInfo ( unique_selected [ 0 ] , ofile )
appendFeatureFrames ( unique_selected [ 0 ] , ofile )
if len ( unique_selected ) > 1 :
FreeCAD . Console . PrintWarning ( " Multi-part export not yet supported. \n " )
2018-08-07 13:50:29 +02:00
FreeCAD . Console . PrintMessage ( " Feature frames of "
+ str ( unique_selected [ 0 ] . Label )
+ " exported to " + str ( ofile ) + " \n " )
2018-01-16 14:38:16 +01:00
2022-02-07 20:54:17 +00:00
def exportGazeboModels ( ) :
import GazeboExport
doc = FreeCAD . activeDocument ( )
for obj in doc . Objects :
""" Export solid shapes. """
if ( isinstance ( obj . Shape , Part . Solid ) if hasattr ( obj , ' Shape ' ) else False ) :
GazeboExport . export_gazebo_model ( obj , os . path . split ( doc . FileName ) [ 0 ] , configs = { } )
elif isinstance ( obj , Part . Feature ) :
FreeCAD . Console . PrintMessage ( ' {0} part is not valid. It has a Compound type, but Solids there are hidden. Please convert it to single Solid ' . format ( obj . Label ) )
2018-01-16 14:38:16 +01:00
###################################################################
# GUI Commands
###################################################################
uidir = os . path . join ( FreeCAD . getUserAppDataDir ( ) ,
" Mod " , __workbenchname__ , " UI " )
icondir = os . path . join ( uidir , " icons " )
2022-02-07 20:54:17 +00:00
2018-01-16 14:38:16 +01:00
spawnClassCommand ( " ExportPartInfoAndFeaturesDialogueCommand " ,
exportPartInfoAndFeaturesDialogue ,
{ " Pixmap " : str ( os . path . join ( icondir , " parttojson.svg " ) ) ,
" MenuText " : " Export info and featureframes " ,
" ToolTip " : " Export part properties (placement, C.O.M) and feature frames " } )
2022-02-07 20:54:17 +00:00
spawnClassCommand ( " ExportGazeboModels " ,
exportGazeboModels ,
{ " Pixmap " : str ( os . path . join ( icondir , " gazeboexport.svg " ) ) ,
" MenuText " : " Export SDF-models to Gazebo " ,
" ToolTip " : " Export SDF-models for all solid parts " } )
2018-01-16 14:38:16 +01:00
###################################################################
# Information from primitive type
###################################################################
def getPrimitiveInfo ( prim_type , subobj , scale = 1e-3 ) :
""" returns a dictionary of the primitive ' s specific information. """
d = { }
if prim_type == " ArcOfCircle " :
2018-01-16 15:29:51 +01:00
d [ " radius " ] = scale * subobj . Curve . Radius
d [ " center " ] = vector2list ( subobj . Curve . Center , scale )
d [ " axis " ] = vector2list ( subobj . Curve . Axis , scale = 1 )
2018-08-07 13:50:29 +02:00
d [ " parameterrange " ] = subobj . ParameterRange
2018-01-16 14:38:16 +01:00
elif prim_type == " ArcOfEllipse " :
2018-01-16 15:29:51 +01:00
d [ " center " ] = vector2list ( subobj . Curve . Center , scale )
d [ " axis " ] = vector2list ( subobj . Curve . Axis , scale = 1 )
d [ " majorradius " ] = scale * subobj . Curve . MajorRadius
d [ " minorradius " ] = scale * subobj . Curve . MinorRadius
d [ " parameterrange " ] = subobj . ParameterRange
2018-01-16 14:38:16 +01:00
elif prim_type == " ArcOfHyperBola " :
2018-01-16 15:29:51 +01:00
d [ " anglexu " ] = subobj . Curve . AngleXU
d [ " axis " ] = vector2list ( subobj . Curve . Axis , scale = 1 )
d [ " center " ] = vector2list ( subobj . Curve . Center , scale )
d [ " majorradius " ] = scale * subobj . Curve . MajorRadius
d [ " minorradius " ] = scale * subobj . Curve . MinorRadius
d [ " parameterrange " ] = subobj . ParameterRange
2018-01-16 14:38:16 +01:00
elif prim_type == " ArcOfParabola " :
2018-01-16 15:29:51 +01:00
d [ " anglexu " ] = subobj . Curve . AngleXU
d [ " axis " ] = vector2list ( subobj . Curve . Axis , scale = 1 )
d [ " center " ] = vector2list ( subobj . Curve . Center , scale )
d [ " focal " ] = scale * subobj . Curve . Focal
2018-01-16 14:38:16 +01:00
elif prim_type == " BSplineCurve " :
FreeCAD . Console . PrintWarning ( " getPrimitiveInfo of BSpline incomplete. " )
elif prim_type == " BezierCurve " :
FreeCAD . Console . PrintWarning ( " getPrimitiveInfo of Bezier incomplete. " )
elif prim_type == " Circle " :
2018-01-16 15:29:51 +01:00
d [ " radius " ] = scale * subobj . Curve . Radius
d [ " center " ] = vector2list ( subobj . Curve . Center , scale )
d [ " axis " ] = vector2list ( subobj . Curve . Axis , scale = 1 )
2018-08-07 13:50:29 +02:00
d [ " parameterrange " ] = subobj . ParameterRange
2018-01-16 14:38:16 +01:00
elif prim_type == " Ellipse " :
2018-01-16 15:29:51 +01:00
d [ " center " ] = vector2list ( subobj . Curve . Center , scale )
d [ " axis " ] = vector2list ( subobj . Curve . Axis , scale = 1 )
d [ " majorradius " ] = scale * subobj . Curve . MajorRadius
d [ " minorradius " ] = scale * subobj . Curve . MinorRadius
d [ " parameterrange " ] = subobj . ParameterRange
2018-01-16 14:38:16 +01:00
elif prim_type == " Hyperbola " :
2018-01-16 15:29:51 +01:00
d [ " anglexu " ] = subobj . Curve . AngleXU
d [ " axis " ] = vector2list ( subobj . Curve . Axis , scale = 1 )
d [ " center " ] = vector2list ( subobj . Curve . Center , scale )
d [ " majorradius " ] = scale * subobj . Curve . MajorRadius
d [ " minorradius " ] = scale * subobj . Curve . MinorRadius
2018-08-07 13:50:29 +02:00
d [ " parameterrange " ] = subobj . ParameterRange
2018-01-16 14:38:16 +01:00
elif prim_type == " Parabola " :
2018-01-16 15:29:51 +01:00
d [ " anglexu " ] = subobj . Curve . AngleXU
d [ " axis " ] = vector2list ( subobj . Curve . Axis , scale = 1 )
d [ " center " ] = vector2list ( subobj . Curve . Center , scale )
d [ " focal " ] = scale * subobj . Curve . Focal
2018-01-16 14:38:16 +01:00
elif prim_type == " Line " :
2019-02-12 10:49:17 +01:00
if int ( FreeCAD . Version ( ) [ 1 ] ) > 16 :
sp = subobj . valueAt ( subobj . FirstParameter )
ep = subobj . valueAt ( subobj . LastParameter )
d [ " startpoint " ] = vector2list ( sp )
d [ " endpoint " ] = vector2list
else :
if not hasattr ( subobj . Curve , " Infinite " ) :
2018-08-07 13:50:29 +02:00
d [ " startpoint " ] = vector2list ( subobj . Curve . StartPoint )
d [ " endpoint " ] = vector2list ( subobj . Curve . EndPoint )
2019-02-12 10:49:17 +01:00
if hasattr ( subobj . Curve , " Infinite " ) :
if subobj . Curve . Infinite :
d [ " infinite " ] = subobj . Curve . Infinite
else :
d [ " startpoint " ] = vector2list ( subobj . Curve . StartPoint )
d [ " endpoint " ] = vector2list ( subobj . Curve . EndPoint )
2018-01-16 14:38:16 +01:00
elif prim_type == " BSplineSurface " :
FreeCAD . Console . PrintWarning ( " getPrimitiveInfo of BSpline incomplete. " )
elif prim_type == " BezierSurface " :
FreeCAD . Console . PrintWarning ( " getPrimitiveInfo of Bezier incomplete. " )
elif prim_type == " Cylinder " :
2018-01-16 15:29:51 +01:00
d [ " axis " ] = vector2list ( subobj . Surface . Axis , scale = 1 )
d [ " radius " ] = scale * subobj . Surface . Radius
d [ " center " ] = vector2list ( subobj . Surface . Center )
2018-01-16 14:38:16 +01:00
PR = list ( subobj . ParameterRange )
PR [ 2 ] = PR [ 2 ] * scale
PR [ 3 ] = PR [ 3 ] * scale
2018-01-16 15:29:51 +01:00
d [ " parameterrange " ] = PR
2018-01-16 14:38:16 +01:00
elif prim_type == " Plane " :
2018-01-16 15:29:51 +01:00
d [ " axis " ] = vector2list ( subobj . Surface . Axis , scale = 1 )
d [ " position " ] = vector2list ( subobj . Surface . Position , scale )
d [ " parameterrange " ] = [ scale * i for i in subobj . ParameterRange ]
2018-01-16 14:38:16 +01:00
elif prim_type == " Sphere " :
2018-01-16 15:29:51 +01:00
d [ " axis " ] = vector2list ( subobj . Surface . Axis , scale = 1 )
d [ " center " ] = vector2list ( subobj . Surface . Center , scale )
d [ " radius " ] = scale * subobj . Surface . Radius
d [ " parameterrange " ] = subobj . ParameterRange
2018-01-16 14:38:16 +01:00
elif prim_type == " Toroid " :
2018-01-16 15:29:51 +01:00
d [ " axis " ] = vector2list ( subobj . Surface . Axis , scale = 1 )
d [ " center " ] = vector2list ( subobj . Surface . Center , scale )
d [ " majorradius " ] = scale * subobj . Surface . MajorRadius
d [ " minorradius " ] = scale * subobj . Surface . MinorRadius
d [ " parameterrange " ] = subobj . Surface . ParameterRange
2018-01-16 14:38:16 +01:00
elif prim_type == " Cone " :
2018-01-16 15:29:51 +01:00
d [ " axis " ] = vector2list ( subobj . Surface . Axis , scale = 1 )
d [ " center " ] = vector2list ( subobj . Surface . Center , scale )
d [ " radius " ] = scale * subobj . Surface . Radius
d [ " semiangle " ] = subobj . Surface . SemiAngle
d [ " parameterrange " ] = subobj . ParameterRange
2018-01-16 14:38:16 +01:00
FreeCAD . Console . PrintWarning ( " getPrimitiveInfo of Cone may have wrong ParameterRange. " )
return d