diff --git a/src/ifcgeom/mapping/IfcFixedReferenceSweptAreaSolid.cpp b/src/ifcgeom/mapping/IfcFixedReferenceSweptAreaSolid.cpp index 805d51b572..16bdfa3c35 100644 --- a/src/ifcgeom/mapping/IfcFixedReferenceSweptAreaSolid.cpp +++ b/src/ifcgeom/mapping/IfcFixedReferenceSweptAreaSolid.cpp @@ -123,9 +123,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcFixedReferenceSweptAreaSolid auto sweep = taxonomy::make( matrix, // matrix4::ptr - no transformation needed profile, // face::ptr - the profile to sweep - nullptr, // item::ptr surface - not used for fixed reference sweep dir // item::ptr curve - the directrix curve - ); // Set the fixed reference direction for the sweep diff --git a/src/ifcgeom/taxonomy.h b/src/ifcgeom/taxonomy.h index af3aa33c4e..d099579cc9 100644 --- a/src/ifcgeom/taxonomy.h +++ b/src/ifcgeom/taxonomy.h @@ -1217,6 +1217,9 @@ typedef item const* ptr; sweep_along_curve(matrix4::ptr m, face::ptr basis, item::ptr surf, item::ptr crv) : sweep(m, basis), surface(surf), curve(crv) {} + // New constructor for fixed reference swept area solid + sweep_along_curve(matrix4::ptr m, face::ptr profile, item::ptr directrix) : sweep(m, profile), surface(nullptr), curve(directrix) { } + virtual size_t calc_hash() const { auto v = std::make_tuple(static_cast(SWEEP_ALONG_CURVE), matrix->hash_components(), basis->calc_hash(), surface->calc_hash(), curve->calc_hash()); return boost::hash{}(v); diff --git a/test/input_temp/simple_sweep_2.ifc b/test/input_temp/simple_sweep_2.ifc new file mode 100644 index 0000000000..11d70bcf81 --- /dev/null +++ b/test/input_temp/simple_sweep_2.ifc @@ -0,0 +1,74 @@ +ISO-10303-21; +HEADER; +FILE_DESCRIPTION(('ViewDefinition[DesignTransferView]'),'2;1'); +FILE_NAME('/dev/null','2025-08-27T11:12:44+02:00',('AdaUser'),('AdaOrg'),'IfcOpenShell 0.8.2','IfcOpenShell 0.8.2','Nobody'); +FILE_SCHEMA(('IFC4X3_ADD2')); +ENDSEC; +DATA; +#1=IFCPROJECT('0bfgwqvaX7Vvg12DS5E4TH',$,'AdaProject',$,$,$,$,(#11),#6); +#2=IFCSIUNIT(*,.LENGTHUNIT.,$,.METRE.); +#3=IFCSIUNIT(*,.AREAUNIT.,$,.SQUARE_METRE.); +#4=IFCSIUNIT(*,.VOLUMEUNIT.,$,.CUBIC_METRE.); +#5=IFCSIUNIT(*,.PLANEANGLEUNIT.,$,.RADIAN.); +#6=IFCUNITASSIGNMENT((#4,#2,#5,#3)); +#7=IFCCARTESIANPOINT((0.,0.,0.)); +#8=IFCDIRECTION((0.,0.,1.)); +#9=IFCDIRECTION((1.,0.,0.)); +#10=IFCAXIS2PLACEMENT3D(#7,#8,#9); +#11=IFCGEOMETRICREPRESENTATIONCONTEXT($,'Model',3,1.E-05,#10,$); +#12=IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Body','Model',*,*,*,*,#11,$,.MODEL_VIEW.,$); +#13=IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Axis','Model',*,*,*,*,#11,$,.GRAPH_VIEW.,$); +#14=IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Box','Model',*,*,*,*,#11,$,.MODEL_VIEW.,$); +#15=IFCACTORROLE(.ENGINEER.,$,$); +#16=IFCPERSON('AdaUser',$,$,$,$,$,(#15),$); +#17=IFCORGANIZATION('ADA','Assembly For Design and Analysis',$,$,$); +#18=IFCPERSONANDORGANIZATION(#16,#17,$); +#19=IFCAPPLICATION(#17,'XXX','ADA','ADA'); +#20=IFCOWNERHISTORY(#18,#19,.READWRITE.,$,$,#18,#19,1756285964); +#21=IFCDIRECTION((0.,0.,1.)); +#22=IFCDIRECTION((1.,0.,0.)); +#23=IFCCARTESIANPOINT((0.,0.,0.)); +#24=IFCAXIS2PLACEMENT3D(#23,#21,#22); +#25=IFCLOCALPLACEMENT($,#24); +#26=IFCSITE('1GDQO$O1L1QOKEaI81COHL',#20,'Ada',$,$,#25,$,$,.ELEMENT.,$,$,$,$,$); +#27=IFCRELAGGREGATES('34vxVzLRfCB8P7OThopnom',#20,'Project Container',$,#1,(#26)); +#28=IFCPROPERTYSINGLEVALUE('project',$,IFCTEXT('AdaProject'),$); +#29=IFCPROPERTYSINGLEVALUE('schema',$,IFCTEXT('IFC4X3_add2'),$); +#30=IFCPROPERTYSET('2hTgvJbh1B7RR4nwsOfRDy',#20,'Properties',$,(#28,#29)); +#31=IFCRELDEFINESBYPROPERTIES('2wzYfhPqT9hwqI5vOO4yex',#20,'Properties',$,(#26),#30); +#32=IFCMATERIAL('S355',$,'Steel'); +#33=IFCPROPERTYSINGLEVALUE('Grade',$,IFCTEXT('S355'),$); +#34=IFCPROPERTYSINGLEVALUE('YieldStress',$,IFCPRESSUREMEASURE(355000000.),$); +#35=IFCPROPERTYSINGLEVALUE('YoungModulus',$,IFCMODULUSOFELASTICITYMEASURE(210000000000.),$); +#36=IFCPROPERTYSINGLEVALUE('PoissonRatio',$,IFCPOSITIVERATIOMEASURE(0.3),$); +#37=IFCPROPERTYSINGLEVALUE('ThermalExpansionCoefficient',$,IFCTHERMALEXPANSIONCOEFFICIENTMEASURE(1.2E-05),$); +#38=IFCPROPERTYSINGLEVALUE('SpecificHeatCapacity',$,IFCSPECIFICHEATCAPACITYMEASURE(0.03),$); +#39=IFCPROPERTYSINGLEVALUE('MassDensity',$,IFCMASSDENSITYMEASURE(7850.),$); +#40=IFCMATERIALPROPERTIES('MaterialMechanical','A Material property description',(#33,#34,#35,#36,#37,#38,#39),#32); +#41=IFCRELASSOCIATESMATERIAL('0vr_O6t$T7vPWIa1EqEt6b',#20,'S355','Objects related to S355',(#64),#32); +#42=IFCDIRECTION((0.,0.,1.)); +#43=IFCDIRECTION((1.,0.,0.)); +#44=IFCCARTESIANPOINT((0.,0.,0.)); +#45=IFCAXIS2PLACEMENT3D(#44,#42,#43); +#46=IFCLOCALPLACEMENT(#25,#45); +#47=IFCCARTESIANPOINTLIST2D(((0.,0.),(0.,0.1),(0.1,0.),(0.1,0.1)),$); +#48=IFCINDEXEDPOLYCURVE(#47,(IFCLINEINDEX((3,1)),IFCLINEINDEX((1,2)),IFCLINEINDEX((2,4)),IFCLINEINDEX((4,3))),$); +#49=IFCARBITRARYCLOSEDPROFILEDEF(.AREA.,$,#48); +#50=IFCCARTESIANPOINTLIST3D(((-100.,-50.,199.610854),(-100.,-50.,200.),(-99.974928791787,-49.9996866104928,199.513897412378),(-99.9060013418686,-49.998825019006,199.441251),(-99.3499585838692,-49.9918744730554,199.093724161494),(-99.2406758662487,-49.9607719931374,198.987781372709),(-99.2000000393918,-49.8803717417563,198.861230109006),(-99.2000000393918,-49.3859696738752,198.235404705615),(-99.1121322022443,-49.2544691526923,198.068948349419),(-98.9000000393918,-49.2000000638752,198.000000135615),(-98.3,-49.1999999172672,197.999999950035)),$); +#51=IFCINDEXEDPOLYCURVE(#50,(IFCLINEINDEX((2,1)),IFCARCINDEX((1,3,4)),IFCLINEINDEX((4,5)),IFCARCINDEX((5,6,7)),IFCLINEINDEX((7,8)),IFCARCINDEX((8,9,10)),IFCLINEINDEX((10,11))),$); +#52=IFCDIRECTION((1.,-0.,0.)); +#53=IFCCARTESIANPOINT((0.,0.,0.)); +#54=IFCDIRECTION((0.,0.,-1.)); +#55=IFCDIRECTION((0.,1.,0.)); +#56=IFCAXIS2PLACEMENT3D(#53,#54,#55); +#57=IFCFIXEDREFERENCESWEPTAREASOLID(#49,#56,#51,$,$,#52); +#58=IFCSHAPEREPRESENTATION(#12,'Body','AdvancedSweptSolid',(#57)); +#59=IFCPRODUCTDEFINITIONSHAPE($,$,(#58)); +#60=IFCCOLOURRGB('Color1',0.8,0.8,0.8); +#61=IFCSURFACESTYLESHADING(#60,0.); +#62=IFCSURFACESTYLE('Color1',.BOTH.,(#61)); +#63=IFCSTYLEDITEM(#57,(#62),'Color1'); +#64=IFCBUILDINGELEMENTPROXY('0pDZhwPyT3dRMnPGA47kAn',#20,'sweep1',$,$,#46,#59,$,$); +#65=IFCRELCONTAINEDINSPATIALSTRUCTURE('196Q7zPfr4LxqeArD0gmJa',#20,'Physical model',$,(#64),#26); +ENDSEC; +END-ISO-10303-21; diff --git a/test/test_sweeps.py b/test/test_sweeps.py index c969011920..f275bb5c98 100644 --- a/test/test_sweeps.py +++ b/test/test_sweeps.py @@ -204,6 +204,15 @@ def test_simple_sweep_1(test_dir): assert occ_shape is not None assert ifc_sz == pytest.approx((1.1, 0.1, 0.89578254)) +def test_simple_sweep_2(test_dir): + ifc_file_path = test_dir / "input_temp/simple_sweep_2.ifc" + ifc_mn, ifc_mx, ifc_sz = load_ifc_mesh_bbox(ifc_file_path) + occ_shape = load_ifc_occ_shape(ifc_file_path) + assert occ_shape is not None + assert ifc_sz == pytest.approx((1.800000679914902, 0.9243618756667757, 2.0958492522636902)) + assert ifc_mn == pytest.approx((-100.1, -50.0, 197.9041507477363)) + assert ifc_mx == pytest.approx((-98.29999932008509, -49.075638124333224, 200.0)) + def test_pipe_12d(test_dir): ifc_file_path = test_dir / "input_temp/pipe.ifc" ifc_mn, ifc_mx, ifc_sz = load_ifc_mesh_bbox(ifc_file_path)