@ -11,248 +11,270 @@ verbose = False
project_folder = os . getcwd ( )
project_folder = os . getcwd ( )
def apply_styles ( page ) :
modified = False
dim_font_size = 3.0
for view in page . Views :
if view . TypeId == ' TechDraw::DrawViewDimension ' :
if view . ViewObject . Fontsize != dim_font_size :
view . ViewObject . Fontsize = dim_font_size
modified = True
return modified
async def generate_2d_drawing ( file_name ) :
async def generate_2d_drawing ( file_name ) :
doc = App . open ( project_folder + ' / ' + file_name )
doc = App . open ( project_folder + ' / ' + file_name )
modified = False
page_name = doc . Name + ' _Drawing '
page_name = doc . Name + ' _Drawing '
if doc . getObject ( page_name ) is not None :
page = doc . getObject ( page_name )
if page is not None :
print ( ' 2D drawing already exists - skipped ' )
print ( ' 2D drawing already exists - skipped ' )
return
template_file_name = project_folder + ' /lib/A4_Landscape_VSPT.svg '
root_objects = [ ]
main_object = None
for obj in doc . Objects :
if len ( obj . Parents ) == 0 :
root_objects . append ( obj )
if obj . Label == doc . Name :
main_object = obj
if main_object is None and len ( root_objects ) == 1 :
main_object = root_objects [ 0 ]
if main_object is None :
raise Exception ( " Can ' t find main object in file " + doc . FileName + " (found " + str ( len ( root_objects ) ) + " root object(s), none named like the document " + doc . Name + " ) " )
code_obj = doc . getObjectsByLabel ( ' Code_Tube_Draft ' )
if len ( code_obj ) == 1 :
code_obj = code_obj [ 0 ]
else :
else :
code_obj = None
modified = True
template_file_name = project_folder + ' /lib/A4_Landscape_VSPT.svg '
sources = [ main_object ]
root_objects = [ ]
bound_box = main_object . Shape . BoundBox
main_object = None
proj_size = [ 0 , 0 , 0 ] # size of the original part front view after projection at scale 1:1
if bound_box . XLength > bound_box . YLength :
for obj in doc . Objects :
if bound_box . XLength > bound_box . ZLength :
if len ( obj . Parents ) == 0 :
main_axis = 0
root_objects . append ( obj )
proj_size [ 0 ] = bound_box . XLength
if obj . Label == doc . Name :
proj_size [ 1 ] = bound_box . ZLength
main_object = obj
proj_size [ 2 ] = bound_box . YLength
if main_object is None and len ( root_objects ) == 1 :
main_object = root_objects [ 0 ]
if main_object is None :
raise Exception ( " Can ' t find main object in file " + doc . FileName + " (found " + str ( len ( root_objects ) ) + " root object(s), none named like the document " + doc . Name + " ) " )
code_obj = doc . getObjectsByLabel ( ' Code_Tube_Draft ' )
if len ( code_obj ) == 1 :
code_obj = code_obj [ 0 ]
else :
else :
main_axis = 2
code_obj = None
proj_size [ 0 ] = bound_box . ZLength
proj_size [ 1 ] = bound_box . XLength
sources = [ main_object ]
proj_size [ 2 ] = bound_box . YLength
else :
bound_box = main_object . Shape . BoundBox
if bound_box . YLength > bound_box . ZLength :
proj_size = [ 0 , 0 , 0 ] # size of the original part front view after projection at scale 1:1
main_axis = 1
if bound_box . XLength > bound_box . YLength :
proj_size [ 0 ] = bound_box . YLength
if bound_box . XLength > bound_box . ZLength :
proj_size [ 1 ] = bound_box . ZLength
main_axis = 0
proj_size [ 2 ] = bound_box . XLength
proj_size [ 0 ] = bound_box . XLength
proj_size [ 1 ] = bound_box . ZLength
proj_size [ 2 ] = bound_box . YLength
else :
main_axis = 2
proj_size [ 0 ] = bound_box . ZLength
proj_size [ 1 ] = bound_box . XLength
proj_size [ 2 ] = bound_box . YLength
else :
else :
main_axis = 2
if bound_box . YLength > bound_box . ZLength :
proj_size [ 0 ] = bound_box . ZLength
main_axis = 1
proj_size [ 1 ] = bound_box . XLength
proj_size [ 0 ] = bound_box . YLength
proj_size [ 2 ] = bound_box . YLength
proj_size [ 1 ] = bound_box . ZLength
proj_size [ 2 ] = bound_box . XLength
if verbose : print ( " Adding drawing page... " ) ;
else :
main_axis = 2
page = doc . addObject ( ' TechDraw::DrawPage ' , page_name )
proj_size [ 0 ] = bound_box . ZLength
template = doc . addObject ( ' TechDraw::DrawSVGTemplate ' , ' Template ' )
proj_size [ 1 ] = bound_box . XLength
proj_size [ 2 ] = bound_box . YLength
template . Template = template_file_name
page . Template = template
if verbose : print ( " Adding drawing page... " ) ;
if verbose : print ( " Computing best scale... " ) ;
page = doc . addObject ( ' TechDraw::DrawPage ' , page_name )
scale_denominators = [ 4.0 , 5.0 , 6.0 , 8.0 , 10.0 ]
template = doc . addObject ( ' TechDraw::DrawSVGTemplate ' , ' Template ' )
scale_numerator = 1.0
scale_denominator = scale_denominators [ 0 ]
template . Template = template_file_name
proj_total_size = [ proj_size [ 0 ] + proj_size [ 2 ] , proj_size [ 1 ] + proj_size [ 2 ] ] # projected size of all views (without spacing) at scale 1:1
page . Template = template
spacingX = 20.0
spacingY = 50.0
if verbose : print ( " Computing best scale... " ) ;
maxSizeX = 280.0
scale_denominators = [ 4.0 , 5.0 , 6.0 , 8.0 , 10.0 ]
maxSizeY = 160.0
scale_numerator = 1.0
for denom in scale_denominators :
scale_denominator = scale_denominators [ 0 ]
scale_denominator = denom
proj_total_size = [ proj_size [ 0 ] + proj_size [ 2 ] , proj_size [ 1 ] + proj_size [ 2 ] ] # projected size of all views (without spacing) at scale 1:1
if proj_total_size [ 0 ] * scale_numerator / denom + spacingX < = maxSizeX and proj_total_size [ 1 ] * scale_numerator / denom + spacingY < = maxSizeY :
spacingX = 20.0
break
spacingY = 50.0
maxSizeX = 280.0
if verbose : print ( " Adding projection group... " ) ;
maxSizeY = 160.0
for denom in scale_denominators :
projGroup = doc . addObject ( ' TechDraw::DrawProjGroup ' , doc . Name + ' _ProjGroup ' )
scale_denominator = denom
page . addView ( projGroup )
if proj_total_size [ 0 ] * scale_numerator / denom + spacingX < = maxSizeX and proj_total_size [ 1 ] * scale_numerator / denom + spacingY < = maxSizeY :
projGroup . ScaleType = ' Custom '
break
projGroup . Scale = scale_numerator / scale_denominator
projGroup . spacingX = 20.0
if verbose : print ( " Adding projection group... " ) ;
projGroup . spacingY = 50.0
projGroup . Source = sources
projGroup = doc . addObject ( ' TechDraw::DrawProjGroup ' , doc . Name + ' _ProjGroup ' )
projGroup . addProjection ( ' Front ' )
page . addView ( projGroup )
if main_axis == 0 :
projGroup . ScaleType = ' Custom '
projGroup . Anchor . Direction = App . Vector ( 0 , 1 , 0 )
projGroup . Scale = scale_numerator / scale_denominator
projGroup . Anchor . XDirection = App . Vector ( - 1 , 0 , 0 )
projGroup . spacingX = 20.0
projGroup . Anchor . RotationVector = App . Vector ( - 1 , 0 , 0 )
projGroup . spacingY = 50.0
elif main_axis == 1 :
projGroup . Source = sources
projGroup . Anchor . Direction = App . Vector ( 1 , 0 , 0 )
projGroup . addProjection ( ' Front ' )
projGroup . Anchor . XDirection = App . Vector ( 0 , 1 , 0 )
if main_axis == 0 :
projGroup . Anchor . RotationVector = App . Vector ( 0 , 1 , 0 )
projGroup . Anchor . Direction = App . Vector ( 0 , 1 , 0 )
elif main_axis == 2 :
projGroup . Anchor . XDirection = App . Vector ( - 1 , 0 , 0 )
projGroup . Anchor . Direction = App . Vector ( 0 , 1 , 0 )
projGroup . Anchor . RotationVector = App . Vector ( - 1 , 0 , 0 )
projGroup . Anchor . XDirection = App . Vector ( 0 , 0 , 1 )
elif main_axis == 1 :
projGroup . Anchor . RotationVector = App . Vector ( 0 , 0 , 1 )
projGroup . Anchor . Direction = App . Vector ( 1 , 0 , 0 )
projGroup . addProjection ( ' Top ' )
projGroup . Anchor . XDirection = App . Vector ( 0 , 1 , 0 )
projGroup . addProjection ( ' Left ' )
projGroup . Anchor . RotationVector = App . Vector ( 0 , 1 , 0 )
projGroup . X = 130.0
elif main_axis == 2 :
projGroup . Y = 150.0
projGroup . Anchor . Direction = App . Vector ( 0 , 1 , 0 )
projGroup . Anchor . XDirection = App . Vector ( 0 , 0 , 1 )
texts = page . Template . EditableTexts
projGroup . Anchor . RotationVector = App . Vector ( 0 , 0 , 1 )
texts [ ' SCALE ' ] = str ( int ( scale_numerator + 0.5 ) ) + ' : ' + str ( int ( scale_denominator + 0.5 ) )
projGroup . addProjection ( ' Top ' )
try :
projGroup . addProjection ( ' Left ' )
texts [ ' PM ' ] = main_object . Assembly_handbook_Material
projGroup . X = 130.0
except :
projGroup . Y = 150.0
pass
texts [ ' PN ' ] = doc . Name
texts = page . Template . EditableTexts
texts [ ' TITLELINE-1 ' ] = doc . Name
texts [ ' SCALE ' ] = str ( int ( scale_numerator + 0.5 ) ) + ' : ' + str ( int ( scale_denominator + 0.5 ) )
page . Template . EditableTexts = texts
try :
texts [ ' PM ' ] = main_object . Assembly_handbook_Material
async def addDimensions ( ) :
except :
for view in projGroup . Views :
pass
if verbose : print ( " View: " + view . Label + " ... " )
texts [ ' PN ' ] = doc . Name
texts [ ' TITLELINE-1 ' ] = doc . Name
edges = [ ]
page . Template . EditableTexts = texts
visibleEdges = view . getVisibleEdges ( )
edgeIdx = 0
async def addDimensions ( ) :
lowestEdgeName = ' '
for view in projGroup . Views :
lowestEdgePos = 1000000
if verbose : print ( " View: " + view . Label + " ... " )
while True :
try :
edges = [ ]
edge = view . getEdgeByIndex ( edgeIdx )
visibleEdges = view . getVisibleEdges ( )
except :
edgeIdx = 0
break
lowestEdgeName = ' '
edges . append ( edge )
lowestEdgePos = 1000000
while True :
if edge . BoundBox . YLength < 0.01 and edge . BoundBox . Center . y < lowestEdgePos :
try :
lowestEdgePos = edge . BoundBox . Center . y
edge = view . getEdgeByIndex ( edgeIdx )
lowestEdgeName = ' Edge ' + str ( edgeIdx )
except :
break
edgeIdx = edgeIdx + 1
edges . append ( edge )
vertices = [ ]
if edge . BoundBox . YLength < 0.01 and edge . BoundBox . Center . y < lowestEdgePos :
vertIdx = 0
lowestEdgePos = edge . BoundBox . Center . y
while True :
lowestEdgeName = ' Edge ' + str ( edgeIdx )
try :
vert = view . getVertexByIndex ( vertIdx )
edgeIdx = edgeIdx + 1
except :
break
vertices = [ ]
vertices . append ( vert )
vertIdx = 0
vertIdx = vertIdx + 1
while True :
try :
def getFeatureName ( edge ) :
vert = view . getVertexByIndex ( vertIdx )
if edge . Curve . TypeId == ' Part::GeomCircle ' :
except :
vertIdx = 0
break
c = edge . BoundBox . Center
vertices . append ( vert )
closestDist = 100000000
vertIdx = vertIdx + 1
closestVert = None
for vert in vertices :
def getFeatureName ( edge ) :
dx = vert . X - c . x
if edge . Curve . TypeId == ' Part::GeomCircle ' :
dy = vert . Y - c . y
vertIdx = 0
dist = math . sqrt ( dx * dx + dy * dy )
c = edge . BoundBox . Center
if dist < closestDist :
closestDist = 100000000
closestDist = dist
closestVert = None
closestVert = vert
for vert in vertices :
vertIdx = vertIdx + 1
dx = vert . X - c . x
if closestVert is not None :
dy = vert . Y - c . y
return ' Vertex ' + str ( vertices . index ( closestVert ) )
dist = math . sqrt ( dx * dx + dy * dy )
if dist < closestDist :
closestDist = dist
closestVert = vert
vertIdx = vertIdx + 1
if closestVert is not None :
return ' Vertex ' + str ( vertices . index ( closestVert ) )
else :
return ' '
else :
else :
return ' '
return ' Edge ' + str ( edges . index ( edge ) )
else :
return ' Edge ' + str ( edges . index ( edge ) )
if verbose : print ( " Listing features... " )
features = [ ]
if verbose : print ( " Listing features... " )
for edge in edges :
features = [ ]
if ( edge . Curve . TypeId == ' Part::GeomLine ' and edge . BoundBox . XLength < = 0.01 ) or ( edge . Curve . TypeId == ' Part::GeomCircle ' and abs ( edge . Curve . Radius * 2.0 - edge . BoundBox . XLength ) < 0.001 and abs ( edge . Curve . Radius * 2.0 - edge . BoundBox . YLength ) < 0.001 ) :
for edge in edges :
featureName = getFeatureName ( edge )
if ( edge . Curve . TypeId == ' Part::GeomLine ' and edge . BoundBox . XLength < = 0.01 ) or ( edge . Curve . TypeId == ' Part::GeomCircle ' and abs ( edge . Curve . Radius * 2.0 - edge . BoundBox . XLength ) < 0.001 and abs ( edge . Curve . Radius * 2.0 - edge . BoundBox . YLength ) < 0.001 ) :
if featureName == ' ' :
featureName = getFeatureName ( edge )
continue
if featureName == ' ' :
continue
pos = edge . BoundBox . Center . x
duplicate = False
for otherFeature in features :
if abs ( otherFeature [ 0 ] - pos ) < 0.1 :
duplicate = True
break
if not duplicate :
features . append ( ( pos , edge , featureName ) )
features . sort ( key = lambda e : e [ 0 ] )
def addDimension ( edgeA , edgeB , posY ) :
dim = doc . addObject ( ' TechDraw::DrawViewDimension ' , ' Dimension ' )
dim . Type = ' DistanceX '
dim . FormatSpec = ' %.1f '
dim . References2D = [ ( view , ( getFeatureName ( edgeA ) , getFeatureName ( edgeB ) ) ) ]
visibleEdgeA = visibleEdges [ edges . index ( edgeA ) ]
visibleEdgeB = visibleEdges [ edges . index ( edgeB ) ]
dim . X = ( visibleEdgeA . BoundBox . Center . x + visibleEdgeB . BoundBox . Center . x ) * 0.5
dim . Y = posY
page . addView ( dim )
if edgeB . Curve . TypeId == ' Part::GeomCircle ' :
if abs ( edgeB . BoundBox . XLength - 6.5 ) > 0.01 :
dim = doc . addObject ( ' TechDraw::DrawViewDimension ' , ' Dimension ' )
dim . Type = ' Diameter '
dim . FormatSpec = ' %.1f '
dim . References2D = [ ( view , ( ' Edge ' + str ( edges . index ( edgeB ) ) , ) ) ]
dim . X = visibleEdgeB . BoundBox . Center . x + 6.0
dim . Y = - 6.0
page . addView ( dim )
if abs ( edgeB . BoundBox . Center . y ) > 0.01 and lowestEdgeName != ' ' :
dim = doc . addObject ( ' TechDraw::DrawViewDimension ' , ' Dimension ' )
dim . Type = ' DistanceY '
dim . FormatSpec = ' %.1f '
dim . References2D = [ ( view , ( getFeatureName ( edgeB ) , lowestEdgeName ) ) ]
dim . X = visibleEdgeB . BoundBox . Center . x + 2.0
dim . Y = - 6.0
page . addView ( dim )
if verbose : print ( " Adding dimensions... " )
if len ( features ) > = 2 :
pos = edge . BoundBox . Center . x
if projGroup . Views . index ( view ) != 0 :
duplicate = False
addDimension ( features [ 0 ] [ 1 ] , features [ len ( features ) - 1 ] [ 1 ] , - 25.0 )
for otherFeature in features :
if abs ( otherFeature [ 0 ] - pos ) < 0.1 :
if len ( features ) > 2 :
duplicate = True
for featureIdx in range ( 0 , len ( features ) - 1 ) :
break
if featureIdx == 0 or features [ featureIdx ] [ 1 ] . Curve . TypeId != ' Part::GeomLine ' :
if not duplicate :
addDimension ( features [ featureIdx ] [ 1 ] , features [ featureIdx + 1 ] [ 1 ] , 15.0 )
features . append ( ( pos , edge , featureName ) )
features . sort ( key = lambda e : e [ 0 ] )
if verbose : print ( " Adding secondary objects... " )
if code_obj is not None :
def addDimension ( edgeA , edgeB , posY ) :
projGroup . Source = projGroup . Source + [ code_obj ]
dim = doc . addObject ( ' TechDraw::DrawViewDimension ' , ' Dimension ' )
dim . Type = ' DistanceX '
page . recompute ( True )
dim . FormatSpec = ' %.1f '
await vspt_coroutine . get_main_loop ( ) . wait ( 1 )
dim . References2D = [ ( view , ( getFeatureName ( edgeA ) , getFeatureName ( edgeB ) ) ) ]
await addDimensions ( )
visibleEdgeA = visibleEdges [ edges . index ( edgeA ) ]
visibleEdgeB = visibleEdges [ edges . index ( edgeB ) ]
if verbose : print ( " Saving... " )
dim . X = ( visibleEdgeA . BoundBox . Center . x + visibleEdgeB . BoundBox . Center . x ) * 0.5
page . recompute ( True )
dim . Y = posY
page . ViewObject . Visibility = False # don't save the document with the page open or it will automatically reopen on load
page . addView ( dim )
doc . save ( )
if edgeB . Curve . TypeId == ' Part::GeomCircle ' :
if abs ( edgeB . BoundBox . XLength - 6.5 ) > 0.01 :
dim = doc . addObject ( ' TechDraw::DrawViewDimension ' , ' Dimension ' )
dim . Type = ' Diameter '
dim . FormatSpec = ' %.1f '
dim . References2D = [ ( view , ( ' Edge ' + str ( edges . index ( edgeB ) ) , ) ) ]
dim . X = visibleEdgeB . BoundBox . Center . x + 6.0
dim . Y = - 6.0
page . addView ( dim )
if abs ( edgeB . BoundBox . Center . y ) > 0.01 and lowestEdgeName != ' ' :
dim = doc . addObject ( ' TechDraw::DrawViewDimension ' , ' Dimension ' )
dim . Type = ' DistanceY '
dim . FormatSpec = ' %.1f '
dim . References2D = [ ( view , ( getFeatureName ( edgeB ) , lowestEdgeName ) ) ]
dim . X = visibleEdgeB . BoundBox . Center . x + 2.0
dim . Y = - 6.0
page . addView ( dim )
if verbose : print ( " Adding dimensions... " )
if len ( features ) > = 2 :
if projGroup . Views . index ( view ) != 0 :
addDimension ( features [ 0 ] [ 1 ] , features [ len ( features ) - 1 ] [ 1 ] , - 25.0 )
if len ( features ) > 2 :
for featureIdx in range ( 0 , len ( features ) - 1 ) :
if featureIdx == 0 or features [ featureIdx ] [ 1 ] . Curve . TypeId != ' Part::GeomLine ' :
addDimension ( features [ featureIdx ] [ 1 ] , features [ featureIdx + 1 ] [ 1 ] , 15.0 )
if verbose : print ( " Adding secondary objects... " )
if code_obj is not None :
projGroup . Source = projGroup . Source + [ code_obj ]
page . recompute ( True )
await vspt_coroutine . get_main_loop ( ) . wait ( 1 )
await addDimensions ( )
if apply_styles ( page ) :
modified = True
if modified :
if verbose : print ( " Saving... " )
page . recompute ( True )
page . ViewObject . Visibility = False # don't save the document with the page open or it will automatically reopen on load
await vspt_coroutine . get_main_loop ( ) . wait ( 1 )
doc . save ( )
if verbose : print ( " Closing... " )
if verbose : print ( " Closing... " )
vspt_freecad . close_all_docs ( )
vspt_freecad . close_all_docs ( )