2222import bcf .v3 .document
2323import bcf .v3 .model
2424import bcf .v3 .topic
25+ import bcf .v3 .visinfo
2526import bpy
2627import bcf
2728import bcf .bcfxml
2829import bcf .v2 .bcfxml
2930import bcf .v2 .model
3031import bcf .v2 .topic
3132import bcf .v2 .visinfo
32- import bcf .agnostic .visinfo
3333import bcf .agnostic .topic
34+ import bcf .agnostic .visinfo
3435import uuid
3536import numpy as np
3637import tempfile
@@ -532,46 +533,78 @@ def poll(cls, context):
532533 def execute (self , context ):
533534 bcfxml = bcfstore .BcfStore .get_bcfxml ()
534535 assert bcfxml
535-
536- if not (version := (bcfxml .version .version_id or "" )).startswith ("2" ):
537- self .report ({"INFO" }, f"BCF { version } is not yet supported: { self .bl_rna .bl_idname } ." )
538- return {"FINISHED" }
536+ bcf_v2 = (bcfxml .version .version_id or "" ).startswith ("2" )
539537
540538 blender_camera = context .scene .camera
541539 assert blender_camera
540+
542541 props = context .scene .BCFProperties
543542 blender_topic = props .active_topic
544543 topic = bcfxml .topics [blender_topic .name ]
545544
546545 direction = blender_camera .matrix_world .to_quaternion () @ Vector ((0.0 , 0.0 , - 1.0 ))
547546 up = blender_camera .matrix_world .to_quaternion () @ Vector ((0.0 , 1.0 , 0.0 ))
548547
549- camera_view_point = bcf .v2 .model .Point (
550- x = blender_camera .location .x , y = blender_camera .location .y , z = blender_camera .location .z
551- )
552- camera_direction = bcf .v2 .model .Direction (x = direction .x , y = direction .y , z = direction .z )
553- camera_up_vector = bcf .v2 .model .Direction (x = up .x , y = up .y , z = up .z )
554- if blender_camera .data .type == "ORTHO" :
555- camera = bcf .v2 .model .OrthogonalCamera (
556- view_to_world_scale = blender_camera .data .ortho_scale ,
557- camera_view_point = camera_view_point ,
558- camera_direction = camera_direction ,
559- camera_up_vector = camera_up_vector ,
548+ blender_render = context .scene .render
549+ assert isinstance (blender_camera .data , bpy .types .Camera )
550+ visinfo_guid = str (uuid .uuid4 ())
551+ if bcf_v2 :
552+ camera_view_point = bcf .v2 .model .Point (
553+ x = blender_camera .location .x , y = blender_camera .location .y , z = blender_camera .location .z
560554 )
561- visualization_info = bcf .v2 .model .VisualizationInfo (orthogonal_camera = camera )
562- elif blender_camera .data .type == "PERSP" :
563- camera = bcf .v2 .model .PerspectiveCamera (
564- field_of_view = degrees (blender_camera .data .angle ),
565- camera_view_point = camera_view_point ,
566- camera_direction = camera_direction ,
567- camera_up_vector = camera_up_vector ,
555+ camera_direction = bcf .v2 .model .Direction (x = direction .x , y = direction .y , z = direction .z )
556+ camera_up_vector = bcf .v2 .model .Direction (x = up .x , y = up .y , z = up .z )
557+ if blender_camera .data .type == "ORTHO" :
558+ camera = bcf .v2 .model .OrthogonalCamera (
559+ view_to_world_scale = blender_camera .data .ortho_scale ,
560+ camera_view_point = camera_view_point ,
561+ camera_direction = camera_direction ,
562+ camera_up_vector = camera_up_vector ,
563+ )
564+ visualization_info = bcf .v2 .model .VisualizationInfo (guid = visinfo_guid , orthogonal_camera = camera )
565+ elif blender_camera .data .type == "PERSP" :
566+ camera = bcf .v2 .model .PerspectiveCamera (
567+ field_of_view = degrees (blender_camera .data .angle ),
568+ camera_view_point = camera_view_point ,
569+ camera_direction = camera_direction ,
570+ camera_up_vector = camera_up_vector ,
571+ )
572+ visualization_info = bcf .v2 .model .VisualizationInfo (guid = visinfo_guid , perspective_camera = camera )
573+ else :
574+ self .report ({"INFO" }, f"Unsupported camera type: '{ blender_camera .data .type } '." )
575+ return {"FINISHED" }
576+ else :
577+ camera_view_point = bcf .v3 .model .Point (
578+ x = blender_camera .location .x , y = blender_camera .location .y , z = blender_camera .location .z
568579 )
569- visualization_info = bcf .v2 .model .VisualizationInfo (guid = str (uuid .uuid4 ()), perspective_camera = camera )
580+ camera_direction = bcf .v3 .model .Direction (x = direction .x , y = direction .y , z = direction .z )
581+ camera_up_vector = bcf .v3 .model .Direction (x = up .x , y = up .y , z = up .z )
582+ cam_aspect = blender_render .resolution_x / blender_render .resolution_y
583+ if blender_camera .data .type == "ORTHO" :
584+ camera = bcf .v3 .model .OrthogonalCamera (
585+ view_to_world_scale = blender_camera .data .ortho_scale ,
586+ camera_view_point = camera_view_point ,
587+ camera_direction = camera_direction ,
588+ camera_up_vector = camera_up_vector ,
589+ aspect_ratio = cam_aspect ,
590+ )
591+ visualization_info = bcf .v3 .model .VisualizationInfo (guid = visinfo_guid , orthogonal_camera = camera )
592+ elif blender_camera .data .type == "PERSP" :
593+ camera = bcf .v3 .model .PerspectiveCamera (
594+ field_of_view = degrees (blender_camera .data .angle ),
595+ camera_view_point = camera_view_point ,
596+ camera_direction = camera_direction ,
597+ camera_up_vector = camera_up_vector ,
598+ aspect_ratio = cam_aspect ,
599+ )
600+ visualization_info = bcf .v3 .model .VisualizationInfo (guid = visinfo_guid , perspective_camera = camera )
601+ else :
602+ self .report ({"INFO" }, f"Unsupported camera type: '{ blender_camera .data .type } '." )
603+ return {"FINISHED" }
570604
571605 # TODO allow the user to enable or disable snapshotting
572606 snapshot = None
573607
574- blender_render = context .scene .render
575608 old_file_format = blender_render .image_settings .file_format
576609 blender_render .image_settings .file_format = "PNG"
577610 old_filepath = blender_render .filepath
@@ -581,11 +614,26 @@ def execute(self, context):
581614 snapshot = f .read ()
582615 # viewpoint.snapshot = blender_render.filepath
583616
584- vizinfo = bcf .v2 .visinfo .VisualizationInfoHandler (visualization_info = visualization_info , snapshot = snapshot )
585- topic .viewpoints [vizinfo .guid + ".bcfv" ] = vizinfo
586- topic .markup .viewpoints .append (
587- bcf .v2 .model .ViewPoint (viewpoint = vizinfo .guid + ".bcfv" , guid = vizinfo .guid , snapshot = vizinfo .guid + ".png" )
588- )
617+ if isinstance (visualization_info , bcf .v2 .model .VisualizationInfo ):
618+ vizinfo = bcf .v2 .visinfo .VisualizationInfoHandler (visualization_info = visualization_info , snapshot = snapshot )
619+ assert isinstance (topic , bcf .v2 .topic .TopicHandler )
620+ topic .viewpoints [vizinfo .guid + ".bcfv" ] = vizinfo
621+ viewpoints = tool .Bcf .get_topic_viewpoints (topic )
622+ viewpoint = bcf .v2 .model .ViewPoint (
623+ viewpoint = vizinfo .guid + ".bcfv" , guid = vizinfo .guid , snapshot = vizinfo .guid + ".png"
624+ )
625+ assert tool .Bcf .is_list_of (viewpoints , bcf .v2 .model .ViewPoint )
626+ viewpoints .append (viewpoint )
627+ else :
628+ vizinfo = bcf .v3 .visinfo .VisualizationInfoHandler (visualization_info = visualization_info , snapshot = snapshot )
629+ assert isinstance (topic , bcf .v3 .topic .TopicHandler )
630+ topic .viewpoints [vizinfo .guid + ".bcfv" ] = vizinfo
631+ viewpoints = tool .Bcf .get_topic_viewpoints (topic )
632+ viewpoint = bcf .v3 .model .ViewPoint (
633+ viewpoint = vizinfo .guid + ".bcfv" , guid = vizinfo .guid , snapshot = vizinfo .guid + ".png"
634+ )
635+ assert tool .Bcf .is_list_of (viewpoints , bcf .v3 .model .ViewPoint )
636+ viewpoints .append (viewpoint )
589637
590638 def get_ifc_elements (objs : list [bpy .types .Object ]) -> list [ifcopenshell .entity_instance ]:
591639 elements = []
@@ -615,27 +663,35 @@ class RemoveBcfViewpoint(bpy.types.Operator):
615663
616664 @classmethod
617665 def poll (cls , context ):
618- return bcf_prop .getBcfViewpoints (None , context )
666+ bcfxml = bcfstore .BcfStore .get_bcfxml ()
667+ if not bcfxml :
668+ return False
669+ props = context .scene .BCFProperties
670+ topic = props .active_topic
671+ if not topic :
672+ return False
673+
674+ topic = props .topics [topic .name ]
675+ if not tool .Blender .get_enum_safe (topic , "viewpoints" ):
676+ cls .poll_message_set ("No viewpoint selected." )
677+ return False
678+ return True
619679
620680 def execute (self , context ):
621681 bcfxml = bcfstore .BcfStore .get_bcfxml ()
622682 assert bcfxml
623683
624- if not (version := (bcfxml .version .version_id or "" )).startswith ("2" ):
625- self .report ({"INFO" }, f"BCF { version } is not yet supported: { self .bl_rna .bl_idname } ." )
626- return {"FINISHED" }
627-
628684 props = context .scene .BCFProperties
629685 blender_topic = props .active_topic
630686 topic = bcfxml .topics [blender_topic .name ]
631- for key , viewpoint in topic .viewpoints . items ():
632- if viewpoint . guid == blender_topic . viewpoints :
633- break
634- del topic . viewpoints [ key ]
635- for i , viewpoint in enumerate (topic . markup .viewpoints ):
636- if viewpoint . guid == blender_topic . viewpoints :
637- break
638- del topic . markup . viewpoints [ i ]
687+ del topic .viewpoints [ blender_topic . viewpoints ]
688+
689+ viewpoints = tool . Bcf . get_topic_viewpoints ( topic )
690+ # Only guid is required attribute for a viewpoint.
691+ vp_index = next ( i for i , vp in enumerate (viewpoints ) if vp . guid in blender_topic .viewpoints )
692+ del viewpoints [ vp_index ]
693+ tool . Bcf . set_topic_viewpoints ( topic , viewpoints )
694+
639695 props .refresh_topic (context )
640696 return {"FINISHED" }
641697
@@ -716,8 +772,8 @@ def poll(cls, context):
716772 def execute (self , context ):
717773 bcfxml = bcfstore .BcfStore .get_bcfxml ()
718774 assert bcfxml
719- bcf_v2 = (bcfxml .version .version_id or "" ).startswith ("2" )
720775
776+ bcf_v2 = (bcfxml .version .version_id or "" ).startswith ("2" )
721777 props = context .scene .BCFProperties
722778 blender_topic = props .active_topic
723779 topic = bcfxml .topics [blender_topic .name ]
@@ -1102,6 +1158,7 @@ def poll(cls, context):
11021158 if blender_topic is None :
11031159 return False
11041160 bcfxml = bcfstore .BcfStore .get_bcfxml ()
1161+ assert bcfxml
11051162 topic = bcfxml .topics [blender_topic .name ]
11061163 return topic .viewpoints
11071164
@@ -1386,9 +1443,8 @@ def create_bitmaps(
13861443 obj = bpy .data .objects .new ("Bitmap" , None )
13871444 obj .empty_display_type = "IMAGE"
13881445 # image = bpy.data.images.load(os.path.join(bcfxml.filepath, topic.guid, bitmap.reference))
1389- # TODO: suuport bcf v3.
13901446 with tempfile .NamedTemporaryFile (delete = False ) as f :
1391- topic .extract_file (bitmap , f .name )
1447+ bcf . agnostic . topic .extract_file (topic , bitmap , outfile = Path ( f .name ) )
13921448 # f.write(bitmap.what)
13931449 image = bpy .data .images .load (f .name )
13941450 src_width = image .size [0 ]
0 commit comments