2025-12-02 16:32:37 +01:00
/********************************************************************************
* *
* This file is part of IfcOpenShell. *
* *
* IfcOpenShell is free software: you can redistribute it and/or modify *
* it under the terms of the Lesser GNU General Public License as published by *
* the Free Software Foundation, either version 3.0 of the License, or *
* (at your option) any later version. *
* *
* IfcOpenShell is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* Lesser GNU General Public License for more details. *
* *
* You should have received a copy of the Lesser GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* *
********************************************************************************/
# include "mapping.h"
# define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell : : geometry ;
# include "../../ifcgeom/profile_helper.h"
# include "../../ifcgeom/infra_sweep_helper.h"
# include <boost/math/constants/constants.hpp>
const double PI = boost : : math : : constants : : pi < double > ( ) ;
# ifdef SCHEMA_HAS_IfcOpenCrossProfileDef
2026-01-04 10:40:02 +01:00
taxonomy : : ptr mapping : : map_impl ( const IfcSchema : : IfcOpenCrossProfileDef & inst ) {
if ( inst . ProfileType ( ) ! = IfcSchema : : IfcProfileTypeEnum : : IfcProfileType_CURVE ) {
2026-07-09 13:30:48 +02:00
logger_ . warning ( " GEO " , 274 , " Expected IfcOpenCrossProfileDef.ProfileType to be CURVE " , inst ) ;
2025-12-02 16:32:37 +01:00
return nullptr ;
}
std : : vector < taxonomy : : point3 : : ptr > points ;
taxonomy : : point3 : : ptr start ;
2026-01-04 10:40:02 +01:00
if ( inst . OffsetPoint ( ) ) {
start = taxonomy : : cast < taxonomy : : point3 > ( map ( inst . OffsetPoint ( ) ) ) ;
2025-12-02 16:32:37 +01:00
} else {
start = taxonomy : : make < taxonomy : : point3 > ( 0. , 0. , 0. ) ;
}
points . push_back ( start ) ;
2026-01-04 10:40:02 +01:00
std : : optional < std : : vector < std : : string > > tags = inst . Tags ( ) ;
std : : optional < std : : string > tag ;
if ( tags . has_value ( ) & & ! tags . value ( ) . empty ( ) ) {
tag = tags . value ( ) [ 0 ] ;
2025-12-02 16:32:37 +01:00
}
2025-12-02 16:34:24 +01:00
// start->tag = tag;
2025-12-02 16:32:37 +01:00
2026-01-04 10:40:02 +01:00
auto widths = inst . Widths ( ) ;
auto angles = inst . Slopes ( ) ; // these are actually angles, but the attribute is called Slopes
2025-12-02 16:32:37 +01:00
if ( widths . size ( ) ! = angles . size ( ) ) {
2026-07-09 13:30:48 +02:00
logger_ . warning ( " GEO " , 275 , " Expected Widths and Slopes to be equal length, but got " + std : : to_string ( widths . size ( ) ) + " and " + std : : to_string ( angles . size ( ) ) + " respectively " , inst ) ;
2025-12-02 16:32:37 +01:00
return nullptr ;
}
2026-01-04 10:40:02 +01:00
auto horizontal_widths = inst . HorizontalWidths ( ) ;
2025-12-02 16:32:37 +01:00
double x = start - > ccomponents ( ) . x ( ) ;
double y = start - > ccomponents ( ) . y ( ) ;
double z = start - > ccomponents ( ) . z ( ) ;
for ( size_t i = 0 ; i < widths . size ( ) ; + + i ) {
double w = widths [ i ] * length_unit_ ;
double a = PI - angles [ i ] * angle_unit_ ;
double dx = ( horizontal_widths ? w : w * std : : cos ( a ) ) ;
double dy = ( horizontal_widths ? w * std : : tan ( a ) : w * std : : sin ( a ) ) ;
double dz = 0. ;
x - = dx ; // subtract because X is positive to the left
y + = dy ;
z + = dz ;
2026-01-04 10:40:02 +01:00
if ( tags . has_value ( ) & & ! tags . value ( ) . empty ( ) ) {
tag = tags . value ( ) [ i + 1 ] ;
2025-12-02 16:32:37 +01:00
}
2025-12-02 16:34:24 +01:00
points . push_back ( taxonomy : : make < taxonomy : : point3 > ( x , y , z ) ) ;
2025-12-02 16:32:37 +01:00
}
auto mapped = polygon_from_points ( points ) ;
2025-12-02 16:34:24 +01:00
/*if (mapped->kind() == taxonomy::LOOP) {
2025-12-02 16:32:37 +01:00
auto r = taxonomy::loop::ptr((taxonomy::loop*)mapped->clone_());
r->closed = false;
return r;
2025-12-02 16:34:24 +01:00
}*/
mapped - > closed = false ;
mapped - > tags = tags ;
2025-12-02 16:32:37 +01:00
return mapped ;
}
# endif