diff --git a/src/bonsai/test/files/snap-target.ifc b/src/bonsai/test/files/snap-target.ifc new file mode 100644 index 0000000000..0b7132dece --- /dev/null +++ b/src/bonsai/test/files/snap-target.ifc @@ -0,0 +1,91 @@ +ISO-10303-21; +HEADER; +FILE_DESCRIPTION(('ViewDefinition[DesignTransferView]'),'2;1'); +FILE_NAME('snap-target.ifc','2026-06-05T17:45:10-03:00',(''),(''),'IfcOpenShell 0.0.0','Bonsai 0.8.6-alpha260605-24a241a','Nobody'); +FILE_SCHEMA(('IFC4')); +ENDSEC; +DATA; +#1=IFCPROJECT('2pZygwkcb1Au$5kgwmW6ZC',$,'My Project',$,$,$,$,(#10,#22),#5); +#2=IFCSIUNIT(*,.LENGTHUNIT.,.MILLI.,.METRE.); +#3=IFCSIUNIT(*,.AREAUNIT.,$,.SQUARE_METRE.); +#4=IFCSIUNIT(*,.VOLUMEUNIT.,$,.CUBIC_METRE.); +#5=IFCUNITASSIGNMENT((#4,#2,#3)); +#6=IFCCARTESIANPOINT((0.,0.,0.)); +#7=IFCDIRECTION((0.,0.,1.)); +#8=IFCDIRECTION((1.,0.,0.)); +#9=IFCAXIS2PLACEMENT3D(#6,#7,#8); +#10=IFCGEOMETRICREPRESENTATIONCONTEXT($,'Model',3,1.E-05,#9,$); +#11=IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Body','Model',*,*,*,*,#10,$,.MODEL_VIEW.,$); +#12=IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Axis','Model',*,*,*,*,#10,$,.GRAPH_VIEW.,$); +#13=IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Box','Model',*,*,*,*,#10,$,.MODEL_VIEW.,$); +#14=IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Annotation','Model',*,*,*,*,#10,$,.SECTION_VIEW.,$); +#15=IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Annotation','Model',*,*,*,*,#10,$,.ELEVATION_VIEW.,$); +#16=IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Annotation','Model',*,*,*,*,#10,$,.MODEL_VIEW.,$); +#17=IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Annotation','Model',*,*,*,*,#10,$,.PLAN_VIEW.,$); +#18=IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Profile','Model',*,*,*,*,#10,$,.ELEVATION_VIEW.,$); +#19=IFCCARTESIANPOINT((0.,0.)); +#20=IFCDIRECTION((1.,0.)); +#21=IFCAXIS2PLACEMENT2D(#19,#20); +#22=IFCGEOMETRICREPRESENTATIONCONTEXT($,'Plan',2,1.E-05,#21,$); +#23=IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Axis','Plan',*,*,*,*,#22,$,.GRAPH_VIEW.,$); +#24=IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Body','Plan',*,*,*,*,#22,$,.PLAN_VIEW.,$); +#25=IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Annotation','Plan',*,*,*,*,#22,$,.PLAN_VIEW.,$); +#26=IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Annotation','Plan',*,*,*,*,#22,$,.REFLECTED_PLAN_VIEW.,$); +#27=IFCSITE('1Lvnr1aSn2OP70jevISY_C',$,'My Site',$,$,#50,$,$,$,$,$,$,$,$); +#33=IFCBUILDING('1NaNtC8Wf6YPU7CZRG8Z8Q',$,'My Building',$,$,#56,$,$,$,$,$,$); +#39=IFCBUILDINGSTOREY('1k9kfaMOr2cvyNvxvoll27',$,'My Storey',$,$,#62,$,$,$,$); +#45=IFCRELAGGREGATES('1plJGwDIHDzwuc7i7gcQQD',$,$,$,#1,(#27)); +#46=IFCCARTESIANPOINT((0.,0.,0.)); +#47=IFCDIRECTION((0.,0.,1.)); +#48=IFCDIRECTION((1.,0.,0.)); +#49=IFCAXIS2PLACEMENT3D(#46,#47,#48); +#50=IFCLOCALPLACEMENT($,#49); +#51=IFCRELAGGREGATES('13KnzD8ZT8bAvAyOQAWiUj',$,$,$,#27,(#33)); +#52=IFCCARTESIANPOINT((0.,0.,0.)); +#53=IFCDIRECTION((0.,0.,1.)); +#54=IFCDIRECTION((1.,0.,0.)); +#55=IFCAXIS2PLACEMENT3D(#52,#53,#54); +#56=IFCLOCALPLACEMENT(#50,#55); +#57=IFCRELAGGREGATES('2Hf4WQLJvE4O43wq$0AZeu',$,$,$,#33,(#39)); +#58=IFCCARTESIANPOINT((0.,0.,0.)); +#59=IFCDIRECTION((0.,0.,1.)); +#60=IFCDIRECTION((1.,0.,0.)); +#61=IFCAXIS2PLACEMENT3D(#58,#59,#60); +#62=IFCLOCALPLACEMENT(#56,#61); +#63=IFCPROPERTYSINGLEVALUE('Symbol',$,IFCLABEL('setout-point'),$); +#64=IFCPROPERTYSET('27lmSbeAXC08EWkEq8XdUG',$,'EPset_Annotation',$,(#63)); +#65=IFCTYPEPRODUCT('0UrP0fLdD5OwzwD41aRKao',$,'SETOUT-POINT',$,'IfcAnnotation/SYMBOL',(#64),$,$); +#66=IFCCARTESIANPOINTLIST3D(((-8999.9990234375,-8999.9990234375,0.),(8999.9990234375,-8999.9990234375,0.),(-8999.9990234375,8999.9990234375,0.),(8999.9990234375,8999.9990234375,0.))); +#67=IFCINDEXEDPOLYGONALFACE((1,2,4,3)); +#68=IFCPOLYGONALFACESET(#66,$,(#67),$); +#69=IFCSHAPEREPRESENTATION(#11,'Body','Tessellation',(#68)); +#70=IFCBUILDINGELEMENTPROXY('3Avrn7zrPBiA7RUh91ENg9',$,'Plane',$,$,#142,#72,$,.COMPLEX.); +#71=IFCRELCONTAINEDINSPATIALSTRUCTURE('0ftVF1Vf1Dmg$p62mtpWVF',$,$,$,(#123,#70,#108),#39); +#72=IFCPRODUCTDEFINITIONSHAPE($,$,(#69)); +#108=IFCBUILDINGELEMENTPROXY('1lwURx5YX5WAXD5ExqQt31',$,'Plane',$,$,#122,#117,$,.COMPLEX.); +#114=IFCCARTESIANPOINTLIST3D(((-5999.99951171875,-2999.99975585938,0.),(5999.99951171875,-2999.99975585938,0.))); +#115=IFCINDEXEDPOLYCURVE(#114,(IFCLINEINDEX((1,2))),$); +#116=IFCSHAPEREPRESENTATION(#11,'Body','Curve3D',(#115)); +#117=IFCPRODUCTDEFINITIONSHAPE($,$,(#116)); +#118=IFCCARTESIANPOINT((0.,0.,0.)); +#119=IFCDIRECTION((0.,0.,1.)); +#120=IFCDIRECTION((1.,0.,0.)); +#121=IFCAXIS2PLACEMENT3D(#118,#119,#120); +#122=IFCLOCALPLACEMENT(#62,#121); +#123=IFCBUILDINGELEMENTPROXY('2X4YMFxHjANvnkl1Hzqjlq',$,'Plane',$,$,#137,#132,$,.COMPLEX.); +#129=IFCCARTESIANPOINTLIST3D(((3000.,-5999.99951171875,0.),(2999.99951171875,5999.99951171875,0.))); +#130=IFCINDEXEDPOLYCURVE(#129,(IFCLINEINDEX((1,2))),$); +#131=IFCSHAPEREPRESENTATION(#11,'Body','Curve3D',(#130)); +#132=IFCPRODUCTDEFINITIONSHAPE($,$,(#131)); +#133=IFCCARTESIANPOINT((0.,0.,0.)); +#134=IFCDIRECTION((0.,0.,1.)); +#135=IFCDIRECTION((1.,0.,0.)); +#136=IFCAXIS2PLACEMENT3D(#133,#134,#135); +#137=IFCLOCALPLACEMENT(#62,#136); +#138=IFCCARTESIANPOINT((0.,0.,0.)); +#139=IFCDIRECTION((0.,0.,1.)); +#140=IFCDIRECTION((1.,0.,0.)); +#141=IFCAXIS2PLACEMENT3D(#138,#139,#140); +#142=IFCLOCALPLACEMENT(#62,#141); +ENDSEC; +END-ISO-10303-21; diff --git a/src/bonsai/test/modal/test_modal.py b/src/bonsai/test/modal/test_modal.py index 27e290ae3f..07ce8b90ed 100644 --- a/src/bonsai/test/modal/test_modal.py +++ b/src/bonsai/test/modal/test_modal.py @@ -296,6 +296,63 @@ def test_snap_far_from_origin(window): yield from preset_event_simulate(window, "RET", "TAP", x, y) yield "FINISHED" +def test_snap_targets(window): + yield from preset_event_simulate(window, "MOUSEMOVE", "NOTHING", 0, 0) + area, region = get_area_and_region(window) + x = round(area.width * 0.44 + area.x) + y = round(area.height * 0.73 + area.y) + + yield from preset_event_simulate(window, "ESC", "TAP", x, y) + + options = [] + props = tool.Snap.get_snap_props() + try: + annotations = props.__annotations__ + except AttributeError: + annotations = type(props).__annotations__ + for prop in annotations.keys(): + if getattr(props, prop): + options.append((prop, props.rna_type.properties[prop].name)) + + for prop, name in options: + any(setattr(props, prop2, prop2 == prop) for prop2, _ in options) # set prop to true and others to false + measure_settings = tool.Project.get_measure_tool_settings() + measure_settings.measurement_type = "POLYLINE" + for obj in tool.Blender.get_selected_objects(): + obj.select_set(False) + with bpy.context.temp_override(area=area, region=region, space_data=area.spaces[0]): + bpy.ops.bim.measure_tool("INVOKE_DEFAULT", measure_type="POLYLINE") + snap_types = [] + yield from preset_event_simulate(window, "MOUSEMOVE", "NOTHING", x, y) + yield from preset_event_simulate(window, "LEFTMOUSE", "TAP", x, y) + snap_type = tool.Model.get_polyline_props().snap_mouse_point[0].snap_type + snap_types.append(snap_type) + + new_x = x + 200 + new_y = y - 55 + yield from preset_event_simulate(window, "MOUSEMOVE", "NOTHING", new_x, new_y) + yield from preset_event_simulate(window, "MOUSEMOVE", "NOTHING", new_x, new_y) + yield from preset_event_simulate(window, "MOUSEMOVE", "NOTHING", new_x, new_y) + yield from preset_event_simulate(window, "MOUSEMOVE", "NOTHING", new_x, new_y) + yield from preset_event_simulate(window, "LEFTMOUSE", "TAP", x, y) + snap_type = tool.Model.get_polyline_props().snap_mouse_point[0].snap_type + snap_types.append(snap_type) + + new_x = x + 130 + new_y = y - 358 + yield from preset_event_simulate(window, "MOUSEMOVE", "NOTHING", new_x, new_y) + yield from preset_event_simulate(window, "MOUSEMOVE", "NOTHING", new_x, new_y) + yield from preset_event_simulate(window, "MOUSEMOVE", "NOTHING", new_x, new_y) + yield from preset_event_simulate(window, "MOUSEMOVE", "NOTHING", new_x, new_y) + yield from preset_event_simulate(window, "LEFTMOUSE", "TAP", x, y) + snap_type = tool.Model.get_polyline_props().snap_mouse_point[0].snap_type + snap_types.append(snap_type) + + yield from preset_event_simulate(window, "ESC", "TAP", x, y) + assert_msg = f"{name} should be in snap_types: {snap_types}" + assert name in snap_types + _assert_pass(assert_msg) + def test_draw_polyline_wall(window, x, y): yield from preset_event_simulate(window, "ESC", "TAP", x, y) area, region = get_area_and_region(window) @@ -358,6 +415,13 @@ def run_tests(): lambda w=window: test_snap_in_xray_mode(w), lambda w=window: test_snap_far_from_origin(w), ] + elif module_name == "snap-target": + filepath = f"./test/files/snap-target.ifc" + bpy.ops.bim.load_project(filepath=filepath) + window = _get_valid_window() + test_queue = [ + lambda w=window: test_snap_targets(w), + ] else: cleanup()