#include #include "vde/brep/pmi_mbd.h" #include "vde/brep/modeling.h" #include "vde/brep/gdt.h" #include using namespace vde::brep; using namespace vde::core; // ═══════════════════════════════════════════════════════════ // PMIAnnotation — basic construction // ═══════════════════════════════════════════════════════════ TEST(PMIMBDTest, Annotation_TypeNames_AllDefined) { PMIAnnotation ann; ann.type = PMIType::Dimension; EXPECT_EQ(ann.type_name(), "DIMENSION"); ann.type = PMIType::GDTCalloutType; EXPECT_EQ(ann.type_name(), "GDT"); ann.type = PMIType::SurfaceFinish; EXPECT_EQ(ann.type_name(), "SURFACE_FINISH"); ann.type = PMIType::DatumTarget; EXPECT_EQ(ann.type_name(), "DATUM_TARGET"); ann.type = PMIType::Note; EXPECT_EQ(ann.type_name(), "NOTE"); ann.type = PMIType::WeldSymbol; EXPECT_EQ(ann.type_name(), "WELD"); } TEST(PMIMBDTest, Annotation_StepAP242_ContainsEntity) { PMIAnnotation ann; ann.type = PMIType::Dimension; ann.label = "TEST_DIM"; ann.content = "10.0 mm"; ann.text_position = Point3D(1, 2, 3); ann.annotation_normal = Vector3D(0, 0, 1); int next_id = 100; auto step = ann.to_step_ap242(next_id); EXPECT_GT(next_id, 100); // Should have consumed IDs EXPECT_NE(step.find("ANNOTATION_OCCURRENCE"), std::string::npos); EXPECT_NE(step.find("TEST_DIM"), std::string::npos); } // ═══════════════════════════════════════════════════════════ // PMIModel — attach / retrieve // ═══════════════════════════════════════════════════════════ TEST(PMIMBDTest, Model_AttachPmi_ReturnsId) { PMIModel model; PMIAnnotation ann; ann.type = PMIType::Note; ann.content = "Test note"; ann.associated_faces = {0, 1}; int id = model.attach_pmi(ann); EXPECT_EQ(id, 1); EXPECT_EQ(model.count(), 1u); } TEST(PMIMBDTest, Model_AttachMultiplePmis_UniqueIds) { PMIModel model; int id1 = model.attach_pmi(PMIAnnotation{}); int id2 = model.attach_pmi(PMIAnnotation{}); int id3 = model.attach_pmi(PMIAnnotation{}); EXPECT_EQ(id1, 1); EXPECT_EQ(id2, 2); EXPECT_EQ(id3, 3); EXPECT_EQ(model.count(), 3u); } TEST(PMIMBDTest, Model_GetAnnotation_ById) { PMIModel model; PMIAnnotation ann; ann.content = "Find me"; int id = model.attach_pmi(ann); const auto* found = model.get_annotation(id); ASSERT_NE(found, nullptr); EXPECT_EQ(found->content, "Find me"); } TEST(PMIMBDTest, Model_GetAnnotation_NotFound) { PMIModel model; EXPECT_EQ(model.get_annotation(9999), nullptr); } TEST(PMIMBDTest, Model_RemovePmi_RemovesFromViews) { PMIModel model; int id = model.attach_pmi(PMIAnnotation{}); EXPECT_TRUE(model.remove_pmi(id)); EXPECT_EQ(model.count(), 0u); EXPECT_EQ(model.get_annotation(id), nullptr); } // ═══════════════════════════════════════════════════════════ // PMIModel — face / edge queries // ═══════════════════════════════════════════════════════════ TEST(PMIMBDTest, Model_AnnotationsForFace_FindsMatches) { PMIModel model; PMIAnnotation ann; ann.associated_faces = {3, 5}; model.attach_pmi(ann); auto found = model.annotations_for_face(3); EXPECT_EQ(found.size(), 1u); auto none = model.annotations_for_face(999); EXPECT_TRUE(none.empty()); } TEST(PMIMBDTest, Model_AnnotationsOfType_Filters) { PMIModel model; PMIAnnotation dim; dim.type = PMIType::Dimension; model.attach_pmi(dim); PMIAnnotation note; note.type = PMIType::Note; model.attach_pmi(note); PMIAnnotation gdt; gdt.type = PMIType::GDTCalloutType; model.attach_pmi(gdt); EXPECT_EQ(model.annotations_of_type(PMIType::Dimension).size(), 1u); EXPECT_EQ(model.annotations_of_type(PMIType::Note).size(), 1u); EXPECT_EQ(model.annotations_of_type(PMIType::GDTCalloutType).size(), 1u); EXPECT_EQ(model.annotations_of_type(PMIType::SurfaceFinish).size(), 0u); } // ═══════════════════════════════════════════════════════════ // PMIView — visibility management // ═══════════════════════════════════════════════════════════ TEST(PMIMBDTest, View_AddAndCheckVisibility) { PMIView view("front"); view.add_annotation(10); view.add_annotation(20); EXPECT_TRUE(view.is_visible(10)); EXPECT_TRUE(view.is_visible(20)); EXPECT_FALSE(view.is_visible(30)); } TEST(PMIMBDTest, View_RemoveAnnotation) { PMIView view; view.add_annotation(10); view.add_annotation(20); view.remove_annotation(10); EXPECT_FALSE(view.is_visible(10)); EXPECT_TRUE(view.is_visible(20)); } TEST(PMIMBDTest, View_SetAllVisible) { PMIView view; view.set_all_visible({1, 2, 3, 4, 5}); EXPECT_TRUE(view.is_visible(1)); EXPECT_TRUE(view.is_visible(5)); EXPECT_FALSE(view.is_visible(10)); EXPECT_EQ(view.visible_annotations().size(), 5u); } TEST(PMIMBDTest, View_ClearAll) { PMIView view; view.set_all_visible({1, 2, 3}); view.clear_all(); EXPECT_TRUE(view.visible_annotations().empty()); } TEST(PMIMBDTest, View_HideAnnotations) { PMIView view; view.set_all_visible({1, 2, 3, 4}); view.hide_annotations({2, 4}); EXPECT_TRUE(view.is_visible(1)); EXPECT_FALSE(view.is_visible(2)); EXPECT_TRUE(view.is_visible(3)); EXPECT_FALSE(view.is_visible(4)); } // ═══════════════════════════════════════════════════════════ // PMIModel — views // ═══════════════════════════════════════════════════════════ TEST(PMIMBDTest, Model_CreateDefaultViews) { PMIModel model; model.attach_pmi(PMIAnnotation{}); model.create_default_views(); EXPECT_NE(model.get_view("front"), nullptr); EXPECT_NE(model.get_view("top"), nullptr); EXPECT_NE(model.get_view("right"), nullptr); EXPECT_NE(model.get_view("iso"), nullptr); } TEST(PMIMBDTest, Model_RemoveView) { PMIModel model; model.set_view("test", PMIView("test")); EXPECT_NE(model.get_view("test"), nullptr); model.remove_view("test"); EXPECT_EQ(model.get_view("test"), nullptr); } // ═══════════════════════════════════════════════════════════ // export_pmi_step_ap242 // ═══════════════════════════════════════════════════════════ TEST(PMIMBDTest, Export_StepAP242_ContainsEntities) { auto box = make_box(10, 5, 3); PMIModel pmi; pmi.attach_pmi(make_pmi_dimension(PMIType::Dimension, 10.0, Point3D(0, 0, 0), {0})); pmi.create_default_views(); auto step = export_pmi_step_ap242(box, pmi); EXPECT_FALSE(step.empty()); EXPECT_NE(step.find("ISO-10303-21"), std::string::npos); EXPECT_NE(step.find("ANNOTATION_OCCURRENCE"), std::string::npos); } TEST(PMIMBDTest, Export_StepAP242_EmptyPmi_StillValid) { auto box = make_box(5, 5, 5); PMIModel pmi; auto step = export_pmi_step_ap242(box, pmi); EXPECT_NE(step.find("ISO-10303-21"), std::string::npos); EXPECT_NE(step.find("ENDSEC"), std::string::npos); } // ═══════════════════════════════════════════════════════════ // Factory functions // ═══════════════════════════════════════════════════════════ TEST(PMIMBDTest, MakePmiDimension_ReturnsConfigured) { auto ann = make_pmi_dimension(PMIType::Dimension, 25.4, Point3D(1, 2, 3), {0, 1}); EXPECT_EQ(ann.type, PMIType::Dimension); EXPECT_EQ(ann.nominal_value, 25.4); EXPECT_EQ(ann.associated_faces.size(), 2u); EXPECT_FALSE(ann.content.empty()); } TEST(PMIMBDTest, MakePmiGdt_ReturnsConfigured) { auto callout = make_gdt_callout(GDTType::Flatness, 0.05); auto ann = make_pmi_gdt(callout, Point3D(10, 20, 0)); EXPECT_EQ(ann.type, PMIType::GDTCalloutType); EXPECT_EQ(ann.gdt_type, GDTType::Flatness); EXPECT_FALSE(ann.content.empty()); } TEST(PMIMBDTest, MakePmiSurfaceFinish_ReturnsConfigured) { auto ann = make_pmi_surface_finish(3.2, 0, Point3D(0, 0, 0)); EXPECT_EQ(ann.type, PMIType::SurfaceFinish); EXPECT_NE(ann.content.find("Ra"), std::string::npos); EXPECT_EQ(ann.associated_faces.size(), 1u); } TEST(PMIMBDTest, MakePmiDatumTarget_ReturnsConfigured) { auto ann = make_pmi_datum_target("A", 0, Point3D(5, 5, 0)); EXPECT_EQ(ann.type, PMIType::DatumTarget); EXPECT_EQ(ann.content, "A"); EXPECT_EQ(ann.associated_faces.size(), 1u); } // ═══════════════════════════════════════════════════════════ // auto_generate_pmi // ═══════════════════════════════════════════════════════════ TEST(PMIMBDTest, AutoGeneratePmi_Box_ProducesAnnotations) { auto box = make_box(10, 5, 3); PMIModel pmi; int count = auto_generate_pmi(box, pmi, DrawingStandard::ISO); EXPECT_GT(count, 0); EXPECT_EQ(pmi.count(), static_cast(count)); // Should have created default views EXPECT_NE(pmi.get_view("front"), nullptr); } TEST(PMIMBDTest, AutoGeneratePmi_EmptyModel_ReturnsZero) { BrepModel empty; PMIModel pmi; int count = auto_generate_pmi(empty, pmi); EXPECT_EQ(count, 0); } // ═══════════════════════════════════════════════════════════ // PMIDisplayProps // ═══════════════════════════════════════════════════════════ TEST(PMIMBDTest, DisplayProps_Defaults) { PMIDisplayProps props; EXPECT_TRUE(props.visible); EXPECT_EQ(props.color, "#000000"); EXPECT_GT(props.text_height, 0.0); EXPECT_TRUE(props.show_leader); EXPECT_FALSE(props.show_frame); }