@@ -323,6 +323,7 @@ class PolylineDecorator:
323323 snap_info = None
324324 tool_state = None
325325 relating_type = None
326+ polyline_points = None
326327
327328 @classmethod
328329 def install (cls , context , ui_only = False ):
@@ -335,7 +336,10 @@ def install(cls, context, ui_only=False):
335336 SpaceView3D .draw_handler_add (handler .draw_snap_point , (context ,), "WINDOW" , "POST_PIXEL" )
336337 )
337338 cls .handlers .append (
338- SpaceView3D .draw_handler_add (handler .draw_measurements , (context ,), "WINDOW" , "POST_PIXEL" )
339+ SpaceView3D .draw_handler_add (handler .select_and_draw_measurements_text , (context ,), "WINDOW" , "POST_PIXEL" )
340+ )
341+ cls .handlers .append (
342+ SpaceView3D .draw_handler_add (handler .select_and_draw_measurements_poly , (context ,), "WINDOW" , "POST_VIEW" )
339343 )
340344 cls .handlers .append (SpaceView3D .draw_handler_add (handler , (context ,), "WINDOW" , "POST_VIEW" ))
341345 cls .is_installed = True
@@ -361,28 +365,20 @@ def update(
361365 cls .tool_state = tool_state
362366 cls .input_ui = input_ui
363367
364- # TODO: unused?
365- @classmethod
366- def set_input_ui (cls , input_ui : tool .Polyline .PolylineUI ) -> None :
367- cls .input_ui = input_ui
368-
369368 @classmethod
370369 def set_angle_axis_line (cls , start : Vector , end : Vector ) -> None :
371370 cls .axis_start = start
372371 cls .axis_end = end
373372
374373 def calculate_measurement_x_y_and_z (self , context : bpy .types .Context ) -> None :
375- polyline_data = context .scene .BIMPolylineProperties .insertion_polyline
376- polyline_points = polyline_data [0 ].polyline_points if polyline_data else []
377-
378- if len (polyline_points ) == 0 or len (polyline_points ) > 2 :
374+ if len (self .polyline_points ) == 0 or len (self .polyline_points ) > 2 :
379375 return None , None
380376
381- start = polyline_points [0 ]
382- if len (polyline_points ) == 1 :
377+ start = self . polyline_points [0 ]
378+ if len (self . polyline_points ) == 1 :
383379 end = context .scene .BIMPolylineProperties .snap_mouse_point [0 ]
384380 else :
385- end = polyline_points [1 ]
381+ end = self . polyline_points [1 ]
386382
387383 x_axis = (Vector ((start .x , start .y , start .z )), Vector ((end .x , start .y , start .z )))
388384 y_axis = (Vector ((end .x , start .y , start .z )), Vector ((end .x , end .y , start .z )))
@@ -423,6 +419,30 @@ def draw_batch(self, shader_type, content_pos, color, indices=None):
423419 shader .uniform_float ("color" , color )
424420 batch .draw (shader )
425421
422+ def shader_config (self , context ):
423+ self .addon_prefs = tool .Blender .get_addon_preferences ()
424+ self .decorator_color = self .addon_prefs .decorations_colour
425+ self .decorator_color_special = self .addon_prefs .decorator_color_special
426+ self .decorator_color_selected = self .addon_prefs .decorator_color_selected
427+ self .decorator_color_error = self .addon_prefs .decorator_color_error
428+ self .decorator_color_unselected = self .addon_prefs .decorator_color_unselected
429+ self .decorator_color_background = self .addon_prefs .decorator_color_background
430+ theme = context .preferences .themes .items ()[0 ][1 ]
431+ self .decorator_color_object_active = (* theme .view_3d .object_active , 1 ) # unwrap color values and adds alpha=1
432+ self .decorator_color_x_axis = (* theme .user_interface .axis_x , 1 )
433+ self .decorator_color_y_axis = (* theme .user_interface .axis_y , 1 )
434+ self .decorator_color_z_axis = (* theme .user_interface .axis_z , 1 )
435+
436+ gpu .state .blend_set ("ALPHA" )
437+ self .line_shader = gpu .shader .from_builtin ("POLYLINE_UNIFORM_COLOR" )
438+ self .line_shader .bind () # required to be able to change uniforms of the shader
439+ # POLYLINE_UNIFORM_COLOR specific uniforms
440+ self .line_shader .uniform_float ("viewportSize" , (context .region .width , context .region .height ))
441+
442+ # general shader
443+ self .shader = gpu .shader .from_builtin ("UNIFORM_COLOR" )
444+ gpu .state .point_size_set (6 )
445+
426446 def draw_input_ui (self , context : bpy .types .Context ) -> None :
427447 texts = {
428448 "D" : "Distance: " ,
@@ -483,17 +503,9 @@ def draw_text_background(self, context, coords_dim, text_dim):
483503 gpu .state .blend_set ("ALPHA" )
484504 self .draw_batch ("TRIS" , verts , color , [(0 , 1 , 2 ), (1 , 2 , 3 )])
485505
486- def draw_measurements (self , context ):
487- region = context .region
506+ def draw_measurements_text (self , context ):
507+ region = bpy . context .region
488508 rv3d = region .data
489- measure_type = context .scene .MeasureToolSettings .measurement_type
490- polyline_data = context .scene .BIMPolylineProperties .insertion_polyline
491- if not polyline_data :
492- return
493- else :
494- polyline_data = context .scene .BIMPolylineProperties .insertion_polyline [0 ]
495- polyline_points = polyline_data .polyline_points
496-
497509 self .addon_prefs = tool .Blender .get_addon_preferences ()
498510 self .font_id = 1
499511 self .shader = gpu .shader .from_builtin ("UNIFORM_COLOR" )
@@ -504,13 +516,15 @@ def draw_measurements(self, context):
504516 color = self .addon_prefs .decorations_colour
505517
506518 blf .color (self .font_id , * color )
507- for i in range (len (polyline_points )):
519+ for i in range (len (self .polyline_points )):
520+ if i < 1 and self .measure_type == "POLY_AREA" :
521+ continue
508522 if i == 0 :
509523 continue
510- dim_text_pos = (Vector (polyline_points [i ].position ) + Vector (polyline_points [i - 1 ].position )) / 2
524+ dim_text_pos = (Vector (self . polyline_points [i ].position ) + Vector (self . polyline_points [i - 1 ].position )) / 2
511525 dim_text_coords = view3d_utils .location_3d_to_region_2d (region , rv3d , dim_text_pos )
512526
513- formatted_value = polyline_points [i ].dim
527+ formatted_value = self . polyline_points [i ].dim
514528
515529 blf .position (self .font_id , dim_text_coords [0 ], dim_text_coords [1 ], 0 )
516530 text = "d: " + formatted_value
@@ -520,19 +534,19 @@ def draw_measurements(self, context):
520534
521535 if i == 1 :
522536 continue
523- angle_text_pos = Vector (polyline_points [i - 1 ].position )
537+ angle_text_pos = Vector (self . polyline_points [i - 1 ].position )
524538 angle_text_coords = view3d_utils .location_3d_to_region_2d (region , rv3d , angle_text_pos )
525539 blf .position (self .font_id , angle_text_coords [0 ], angle_text_coords [1 ], 0 )
526- text = "a: " + polyline_points [i ].angle
540+ text = "a: " + self . polyline_points [i ].angle
527541 text_length = blf .dimensions (self .font_id , text )
528542 self .draw_text_background (context , angle_text_coords , text_length )
529543 blf .draw (self .font_id , text )
530544
531- if measure_type == "SINGLE" :
545+ if self . measure_type == "SINGLE" :
532546 axis_line , axis_line_center = self .calculate_measurement_x_y_and_z (context )
533547 for i , dim_text_pos in enumerate (axis_line_center ):
534548 dim_text_coords = view3d_utils .location_3d_to_region_2d (region , rv3d , dim_text_pos )
535- blf .position (self .font_id , dim_text_coords [0 ], dim_text_coords [1 ], 0 )
549+ pos = blf .position (self .font_id , dim_text_coords [0 ], dim_text_coords [1 ], 0 )
536550 value = round ((axis_line [i ][1 ] - axis_line [i ][0 ]).length , 4 )
537551 direction = axis_line [i ][1 ] - axis_line [i ][0 ]
538552 if (i == 0 and direction .x < 0 ) or (i == 1 and direction .y < 0 ) or (i == 2 and direction .z < 0 ):
@@ -545,10 +559,10 @@ def draw_measurements(self, context):
545559 blf .draw (self .font_id , text )
546560
547561 # Area and Length text
548- polyline_verts = [Vector ((p .x , p .y , p .z )) for p in polyline_points ]
562+ polyline_verts = [Vector ((p .x , p .y , p .z )) for p in self . polyline_points ]
549563
550564 # Area
551- if measure_type == "POLY_AREA" and polyline_data .area :
565+ if self . measure_type == "POLY_AREA" and self . polyline_data .area :
552566 if len (polyline_verts ) < 3 :
553567 return
554568 center = sum (polyline_verts , Vector ()) / len (polyline_verts ) # Center between all polyline points
@@ -557,7 +571,7 @@ def draw_measurements(self, context):
557571 polyline_verts [:- 1 ]
558572 ) # Doesn't use the last point if is a closed polyline
559573 area_text_coords = view3d_utils .location_3d_to_region_2d (region , rv3d , center )
560- value = polyline_data .area
574+ value = self . polyline_data .area
561575 text = f"area: { value } "
562576 text_length = blf .dimensions (self .font_id , text )
563577 area_text_coords [0 ] -= text_length [0 ] / 2 # Center text horizontally
@@ -566,19 +580,85 @@ def draw_measurements(self, context):
566580 blf .draw (self .font_id , text )
567581
568582 # Length
569- if measure_type in {"POLYLINE" , "POLY_AREA" }:
583+ if self . measure_type in {"POLYLINE" , "POLY_AREA" }:
570584 if len (polyline_verts ) < 3 :
571585 return
572586 total_length_text_coords = view3d_utils .location_3d_to_region_2d (region , rv3d , polyline_verts [- 1 ])
573587 blf .position (self .font_id , total_length_text_coords [0 ], total_length_text_coords [1 ], 0 )
574- value = polyline_data .total_length
588+ value = self . polyline_data .total_length
575589 text = f"length: { value } "
576590 text_length = blf .dimensions (self .font_id , text )
577591 self .draw_text_background (context , total_length_text_coords , text_length )
578592 blf .draw (self .font_id , text )
579593
580594 blf .disable (self .font_id , blf .SHADOW )
581595
596+ def draw_measurements_poly (self , context ):
597+ self .shader_config (context )
598+ polyline_verts : list [Vector ] = []
599+ polyline_edges : list [list [int ]] = []
600+ for point_prop in self .polyline_points :
601+ point = Vector ((point_prop .x , point_prop .y , point_prop .z ))
602+ polyline_verts .append (point )
603+
604+ for i in range (len (polyline_verts ) - 1 ):
605+ polyline_edges .append ([i , i + 1 ])
606+
607+ # Lines for X, Y, Z of single measure
608+ if self .polyline_data and self .polyline_data .measurement_type == "SINGLE" :
609+ axis , _ = self .calculate_measurement_x_y_and_z (context )
610+ x_axis , y_axis , z_axis = axis
611+ self .draw_batch ("LINES" , [* x_axis ], self .decorator_color_x_axis , [(0 , 1 )])
612+ self .draw_batch ("LINES" , [* y_axis ], self .decorator_color_y_axis , [(0 , 1 )])
613+ self .draw_batch ("LINES" , [* z_axis ], self .decorator_color_z_axis , [(0 , 1 )])
614+
615+ # Area highlight
616+ if self .polyline_data :
617+ area = self .polyline_data .area .split (" " )[0 ]
618+ if self .polyline_data .measurement_type == "POLY_AREA" and area :
619+ if float (area ) > 0 :
620+ tris = self .calculate_polygon (polyline_verts )["tris" ]
621+ self .draw_batch ("TRIS" , polyline_verts , transparent_color (self .decorator_color_special ), tris )
622+
623+ # Draw polyline with selected points
624+ self .line_shader .uniform_float ("lineWidth" , 2.0 )
625+ self .draw_batch ("POINTS" , polyline_verts , self .decorator_color_special )
626+ if len (polyline_verts ) > 1 :
627+ self .draw_batch ("LINES" , polyline_verts , self .decorator_color_special , polyline_edges )
628+
629+ def get_polylines_data (self , context ):
630+ self .measure_type = context .scene .MeasureToolSettings .measurement_type
631+ self .polyline_data = context .scene .BIMPolylineProperties .insertion_polyline
632+ self .measure_data = context .scene .BIMPolylineProperties .measurement_polyline
633+
634+ def select_and_draw_measurements_text (self , context ):
635+ self .get_polylines_data (context )
636+ if self .polyline_data :
637+ self .polyline_data = context .scene .BIMPolylineProperties .insertion_polyline [0 ]
638+ self .polyline_points = self .polyline_data .polyline_points
639+ self .draw_measurements_text (context )
640+
641+ if self .measure_data :
642+ for polyline_data in self .measure_data :
643+ self .polyline_data = polyline_data
644+ self .measure_type = polyline_data .measurement_type
645+ self .polyline_points = self .polyline_data .polyline_points
646+ self .draw_measurements_text (context )
647+
648+ def select_and_draw_measurements_poly (self , context ):
649+ self .get_polylines_data (context )
650+ if self .polyline_data :
651+ self .polyline_data = context .scene .BIMPolylineProperties .insertion_polyline [0 ]
652+ self .polyline_points = self .polyline_data .polyline_points
653+ self .draw_measurements_poly (context )
654+
655+ if self .measure_data :
656+ for polyline_data in self .measure_data :
657+ self .polyline_data = polyline_data
658+ self .measure_type = polyline_data .measurement_type
659+ self .polyline_points = self .polyline_data .polyline_points
660+ self .draw_measurements_poly (context )
661+
582662 def draw_snap_point (self , context ):
583663 self .line_shader = gpu .shader .from_builtin ("POLYLINE_UNIFORM_COLOR" )
584664 self .line_shader .bind () # required to be able to change uniforms of the shader
@@ -736,6 +816,7 @@ def __call__(self, context):
736816 polyline_points = polyline_data .polyline_points
737817 else :
738818 polyline_points = []
819+ self .polyline_points = polyline_points
739820 polyline_verts : list [Vector ] = []
740821 polyline_edges : list [list [int ]] = []
741822 for point_prop in polyline_points :
@@ -764,21 +845,21 @@ def __call__(self, context):
764845 self .line_shader .uniform_float ("lineWidth" , 0.75 )
765846 self .draw_batch ("LINES" , [self .axis_start , self .axis_end ], axis_color , [(0 , 1 )])
766847
767- # Lines for X, Y, Z of single measure
768- if polyline_data and polyline_data .measurement_type == "SINGLE" :
769- axis , _ = self .calculate_measurement_x_y_and_z (context )
770- x_axis , y_axis , z_axis = axis
771- self .draw_batch ("LINES" , [* x_axis ], decorator_color_x_axis , [(0 , 1 )])
772- self .draw_batch ("LINES" , [* y_axis ], decorator_color_y_axis , [(0 , 1 )])
773- self .draw_batch ("LINES" , [* z_axis ], decorator_color_z_axis , [(0 , 1 )])
774-
775- # Area highlight
776- if polyline_data :
777- area = polyline_data .area .split (" " )[0 ]
778- if polyline_data .measurement_type == "POLY_AREA" and area :
779- if float (area ) > 0 :
780- tris = self .calculate_polygon (polyline_verts )["tris" ]
781- self .draw_batch ("TRIS" , polyline_verts , transparent_color (decorator_color_special ), tris )
848+ # # Lines for X, Y, Z of single measure
849+ # if polyline_data and polyline_data.measurement_type == "SINGLE":
850+ # axis, _ = self.calculate_measurement_x_y_and_z(context)
851+ # x_axis, y_axis, z_axis = axis
852+ # self.draw_batch("LINES", [*x_axis], decorator_color_x_axis, [(0, 1)])
853+ # self.draw_batch("LINES", [*y_axis], decorator_color_y_axis, [(0, 1)])
854+ # self.draw_batch("LINES", [*z_axis], decorator_color_z_axis, [(0, 1)])
855+
856+ # # Area highlight
857+ # if polyline_data:
858+ # area = polyline_data.area.split(" ")[0]
859+ # if polyline_data.measurement_type == "POLY_AREA" and area:
860+ # if float(area) > 0:
861+ # tris = self.calculate_polygon(polyline_verts)["tris"]
862+ # self.draw_batch("TRIS", polyline_verts, transparent_color(decorator_color_special), tris)
782863
783864 # Mouse points
784865 if snap_prop .snap_type in ["Plane" , "Axis" , "Mix" ]:
0 commit comments