| 24 | #include <boost/math/constants/constants.hpp> |
| 25 | |
| 26 | taxonomy::ptr mapping::map_impl(const IfcSchema::IfcTrimmedCurve* inst) { |
| 27 | static const double pi = boost::math::constants::pi<double>(); |
| 28 | |
| 29 | IfcSchema::IfcCurve* basis_curve = inst->BasisCurve(); |
| 30 | bool isConic = basis_curve->declaration().is(IfcSchema::IfcConic::Class()); |
| 31 | double parameterFactor = isConic ? angle_unit_ : length_unit_; |
| 32 | |
| 33 | auto tc = taxonomy::make<taxonomy::edge>(); |
| 34 | tc->basis = map(inst->BasisCurve()); |
| 35 | |
| 36 | bool trim_cartesian = inst->MasterRepresentation() != IfcSchema::IfcTrimmingPreference::IfcTrimmingPreference_PARAMETER; |
| 37 | auto trims1 = inst->Trim1(); |
| 38 | auto trims2 = inst->Trim2(); |
| 39 | |
| 40 | // reversed orientation handling happens in geometry kernel |
| 41 | unsigned sense_agreement = 0; |
| 42 | double flts[2]; |
| 43 | taxonomy::point3::ptr pnts[2]; |
| 44 | bool has_flts[2] = {false,false}; |
| 45 | bool has_pnts[2] = {false,false}; |
| 46 | |
| 47 | tc->curve_sense = inst->SenseAgreement(); |
| 48 | |
| 49 | for (auto it = trims1->begin(); it != trims1->end(); it ++) { |
| 50 | auto i = *it; |
| 51 | if (i->as<IfcSchema::IfcCartesianPoint>()) { |
| 52 | pnts[sense_agreement] = taxonomy::cast<taxonomy::point3>(map(i)); |
| 53 | has_pnts[sense_agreement] = true; |
| 54 | } else if (i->as<IfcSchema::IfcParameterValue>()) { |
| 55 | const double value = *i->as<IfcSchema::IfcParameterValue>(); |
| 56 | flts[sense_agreement] = value * parameterFactor; |
| 57 | has_flts[sense_agreement] = true; |
| 58 | } |
| 59 | } |
| 60 | |
| 61 | for (auto it = trims2->begin(); it != trims2->end(); it ++) { |
| 62 | auto i = *it; |
| 63 | if (i->as<IfcSchema::IfcCartesianPoint>()) { |
| 64 | pnts[1 - sense_agreement] = taxonomy::cast<taxonomy::point3>(map(i)); |
| 65 | has_pnts[1-sense_agreement] = true; |
| 66 | } else if (i->as<IfcSchema::IfcParameterValue>()) { |
| 67 | const double value = *i->as<IfcSchema::IfcParameterValue>(); |
| 68 | flts[1-sense_agreement] = value * parameterFactor; |
| 69 | has_flts[1-sense_agreement] = true; |
| 70 | } |
| 71 | } |
| 72 | |
| 73 | const double tol = settings_.get<settings::Precision>().get(); |
| 74 | |
| 75 | trim_cartesian &= has_pnts[0] && has_pnts[1]; |
| 76 | bool trim_cartesian_failed = !trim_cartesian; |
| 77 | if (trim_cartesian) { |
| 78 | if ((pnts[0]->ccomponents() - pnts[1]->ccomponents()).norm() < (2 * tol)) { |
| 79 | Logger::Message(Logger::LOG_WARNING, "Skipping segment with length below tolerance level:", inst); |
| 80 | return nullptr; |
| 81 | } |
| 82 | tc->start = pnts[0]; |
| 83 | tc->end = pnts[1]; |