@ -99,7 +99,7 @@ class RasterView:
def _should_render ( self , obj ) :
return obj . TypeId in [ ' Part::Feature ' , ' Part::FeaturePython ' , ' PartDesign::Body ' , ' Part::Mirroring ' , ' Part::Cut ' , ' Part::Part2DObjectPython ' ]
def render ( self ) :
def render ( self , fast_render = True ) :
from pivy import coin
import os
from PIL import Image , ImageDraw , ImageChops
@ -141,6 +141,7 @@ class RasterView:
is_new_part = workbench . techDrawExtensions . isNewPartInView ( view , part )
if not fast_render :
is_conflicting = False
if link . LinkedObject in duplicated_parts . keys ( ) :
link . LinkedObject = duplicated_parts [ link . LinkedObject ]
@ -173,6 +174,7 @@ class RasterView:
continue
if self . _should_render ( obj ) :
if not fast_render :
objects_to_reset [ obj ] = (
obj . ViewObject . Visibility ,
obj . ViewObject . LineColor ,
@ -218,16 +220,18 @@ class RasterView:
resolution [ 0 ] = int ( resolution [ 0 ] * max_res / resolution [ 1 ] )
resolution [ 1 ] = int ( max_res )
if fast_render :
composite_img = self . _render_lines ( tmp_doc , resolution , prev_parts + new_parts , ( 0.0 , 0.0 , 0.0 ) , [ ] )
else :
# render old parts in gray lines
prev_parts_img = self . _render_lines ( tmp_doc , resolution , prev_parts , ( 0.6 , 0.6 , 0.6 ) , [ ] )
prev_parts_img = self . _render_lines ( tmp_doc , resolution , prev_parts , ( 0.6 , 0.6 , 0.6 ) , [ ] , fast_render )
# render new parts in black lines (old parts can mask them)
new_parts_img = self . _render_lines ( tmp_doc , resolution , new_parts , ( 0.0 , 0.0 , 0.0 ) , prev_parts )
new_parts_img = self . _render_lines ( tmp_doc , resolution , new_parts , ( 0.0 , 0.0 , 0.0 ) , prev_parts , fast_render )
# create the composite image
composite_img = prev_parts_img . copy ( )
composite_img . paste ( new_parts_img , None , new_parts_img )
#composite_img = new_parts_img.copy()
finally :
# restore properties on objects we have modified
@ -289,7 +293,7 @@ class RasterView:
image . ImageFile = self . image_file_name # TODO: see if it's possible to set a relative path
image . recompute ( )
def _render_lines ( self , doc , resolution , parts , line_color , masking_parts ) :
def _render_lines ( self , doc , resolution , parts , line_color , masking_parts , fast_render = True ) :
import tempfile
from PIL import Image , ImageDraw , ImageFilter
@ -303,7 +307,7 @@ class RasterView:
# in current version of freecad, link override material does not allow to override all material properties, for example emissive color, so we have to change material of the linked object
for obj in self . _flatten_objects_tree ( [ link ] ) :
if self . _should_render ( obj ) :
if self . _should_render ( obj ) and not fast_render :
obj . ViewObject . LineColor = ( 0.0 , 0.0 , 0.0 , 0.0 ) if link in parts else ( 1.0 , 0.0 , 1.0 )
obj . ViewObject . ShapeMaterial . AmbientColor = ( 0.0 , 0.0 , 0.0 , 0.0 )
obj . ViewObject . ShapeMaterial . DiffuseColor = ( 0.0 , 0.0 , 0.0 , 0.0 )
@ -325,6 +329,8 @@ class RasterView:
lines_img = lines_bands [ 1 ]
alpha_img = lines_bands [ 0 ] . point ( lambda p : 255 - p )
generate_outlines = not fast_render
if generate_outlines :
# Render all shapes with different colors, in order to extract outlines (where color changes)
# This is needed because FreeCAD does not render lines on the boundary of curve shapes, such as spheres or cylinders
# The technique could be improved by using the depth buffer instead, in order to detect boundaries within the same object
@ -381,6 +387,8 @@ class RasterView:
alpha_fullres = alpha_img . resize ( outlines_img . size , Image . NEAREST )
alpha_fullres . paste ( outlines_img . point ( lambda p : 255 ) , None , outlines_img . point ( lambda p : 255 if p == 0 else 0 ) )
alpha_img = alpha_fullres . resize ( all_lines . size , Image . BILINEAR )
else :
all_lines = lines_img
# colorize final image
fill_color = ( 1.0 , 1.0 , 1.0 )
@ -388,7 +396,7 @@ class RasterView:
all_lines . point ( lambda p : int ( fill_color [ 0 ] * p + line_color [ 0 ] * ( 255.0 - p ) ) ) ,
all_lines . point ( lambda p : int ( fill_color [ 1 ] * p + line_color [ 1 ] * ( 255.0 - p ) ) ) ,
all_lines . point ( lambda p : int ( fill_color [ 2 ] * p + line_color [ 2 ] * ( 255.0 - p ) ) ) ,
alpha_img
alpha_img . point ( lambda p : 0 if p == 0 else 255 )
] )
# crop 1px borders