X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModelGeomAlgo%2FModelGeomAlgo_Point2D.cpp;h=b950621449bd1742f903e7e8e6386b97bce40858;hb=06e7f5859095193fc7f498bd89a7d28009794f53;hp=2060572394512a05f00a6cc8bcf58e09b1790865;hpb=0bada2df7b7948c756effe42fe860cc1b93b77af;p=modules%2Fshaper.git diff --git a/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.cpp b/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.cpp old mode 100755 new mode 100644 index 206057239..b95062144 --- a/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.cpp +++ b/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.cpp @@ -1,14 +1,33 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D - -// File: ModelAPI_Tools.cpp -// Created: 20 Jul 2016 -// Author: Natalia ERMOLAEVA +// Copyright (C) 2014-2023 CEA, EDF +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library 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 GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// #include "ModelGeomAlgo_Point2D.h" #include #include #include +#include +#include + +#include + +#include #include #include @@ -20,106 +39,288 @@ #include #include #include +#include + +//#define DEBUG_POINT_INSIDE_SHAPE +#ifdef DEBUG_POINT_INSIDE_SHAPE +#include +#endif #ifdef WIN32 #pragma warning(disable : 4996) // for sprintf #endif -namespace ModelGeomAlgo_Point2D { - std::shared_ptr getPointOfRefAttr(ModelAPI_Feature* theFeature, +std::shared_ptr ModelGeomAlgo_Point2D::getPointOfRefAttr( + ModelAPI_Feature* theFeature, const std::string& theAttribute, const std::string& theObjectFeatureKind, const std::string& theObjectFeatureAttribute) - { - std::shared_ptr aPointAttr; - - /// essential check as it is called in openGl thread - if (!theFeature || !theFeature->data().get() || !theFeature->data()->isValid()) - return std::shared_ptr(); - - FeaturePtr aFeature; - std::shared_ptr anAttr = std::dynamic_pointer_cast< - ModelAPI_AttributeRefAttr>(theFeature->data()->attribute(theAttribute)); - if(anAttr.get() && anAttr->isInitialized()) { - aFeature = ModelAPI_Feature::feature(anAttr->object()); - if (aFeature.get()) { - bool aFeatureOfObjectKind = !theObjectFeatureKind.empty() && - !theObjectFeatureAttribute.empty() && - aFeature->getKind() == theObjectFeatureKind; - if(aFeatureOfObjectKind) - aPointAttr = std::dynamic_pointer_cast( - aFeature->data()->attribute(theObjectFeatureAttribute)); - else if (anAttr->attr()) - aPointAttr = std::dynamic_pointer_cast(anAttr->attr()); - } +{ + std::shared_ptr aPointAttr; + + /// essential check as it is called in openGl thread + if (!theFeature || !theFeature->data().get() || !theFeature->data()->isValid()) + return std::shared_ptr(); + + FeaturePtr aFeature; + std::shared_ptr anAttr = std::dynamic_pointer_cast< + ModelAPI_AttributeRefAttr>(theFeature->data()->attribute(theAttribute)); + if(anAttr.get() && anAttr->isInitialized()) { + aFeature = ModelAPI_Feature::feature(anAttr->object()); + if (aFeature.get()) { + bool aFeatureOfObjectKind = !theObjectFeatureKind.empty() && + !theObjectFeatureAttribute.empty() && + aFeature->getKind() == theObjectFeatureKind; + if(aFeatureOfObjectKind) + aPointAttr = std::dynamic_pointer_cast( + aFeature->data()->attribute(theObjectFeatureAttribute)); + else if (anAttr->attr()) + aPointAttr = std::dynamic_pointer_cast(anAttr->attr()); } - return aPointAttr; } + return aPointAttr; +} - void getPointsOfReference(const std::shared_ptr& theObject, +void ModelGeomAlgo_Point2D::getPointsOfReference( + const std::shared_ptr& theObject, const std::string& theReferenceFeatureKind, std::set >& theAttributes, const std::string& theObjectFeatureKind, const std::string& theObjectFeatureAttribute, const bool isSkipFeatureAttributes) - { - // find by feature - FeaturePtr aSourceFeature = ModelAPI_Feature::feature(theObject); - - const std::set& aRefsList = theObject->data()->refsToMe(); - std::set::const_iterator aIt; - for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) { - std::shared_ptr aAttr = (*aIt); - FeaturePtr aRefFeature = std::dynamic_pointer_cast(aAttr->owner()); - if (aRefFeature->getKind() == theReferenceFeatureKind) { - std::list anAttributes = - aRefFeature->data()->attributes(ModelAPI_AttributeRefAttr::typeId()); - std::list::iterator anIter = anAttributes.begin(), aLast = anAttributes.end(); - bool isSkippedAttribute = false; - if (isSkipFeatureAttributes) { - for(anIter = anAttributes.begin(); anIter != aLast && !isSkippedAttribute; anIter++) { - AttributeRefAttrPtr aRefAttribute = - std::dynamic_pointer_cast(*anIter); - if (aRefAttribute.get() && !aRefAttribute->isObject()) { - std::shared_ptr aPointAttr = - std::dynamic_pointer_cast(aRefAttribute->attr()); - FeaturePtr anAttributeFeature = ModelAPI_Feature::feature(aPointAttr->owner()); - isSkippedAttribute = aSourceFeature == anAttributeFeature; - } - } - } - if (isSkippedAttribute) - continue; +{ + // find by feature + FeaturePtr aSourceFeature = ModelAPI_Feature::feature(theObject); - // it searches the first point of AttributeRefAtt - std::shared_ptr aPointAttr; - for(anIter = anAttributes.begin(); anIter != aLast && !aPointAttr.get(); anIter++) { + const std::set& aRefsList = theObject->data()->refsToMe(); + std::set::const_iterator aIt; + for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) { + std::shared_ptr aAttr = (*aIt); + FeaturePtr aRefFeature = std::dynamic_pointer_cast(aAttr->owner()); + if (aRefFeature->getKind() == theReferenceFeatureKind) { + std::list anAttributes = + aRefFeature->data()->attributes(ModelAPI_AttributeRefAttr::typeId()); + std::list::iterator anIter = anAttributes.begin(), aLast = anAttributes.end(); + bool isSkippedAttribute = false; + if (isSkipFeatureAttributes) { + for(anIter = anAttributes.begin(); anIter != aLast && !isSkippedAttribute; anIter++) { AttributeRefAttrPtr aRefAttribute = std::dynamic_pointer_cast(*anIter); - if (aRefAttribute.get()) { - aPointAttr = getPointOfRefAttr(aRefFeature.get(), aRefAttribute->id(), - theObjectFeatureKind, theObjectFeatureAttribute); + if (aRefAttribute.get() && !aRefAttribute->isObject()) { + std::shared_ptr aPointAttr = + std::dynamic_pointer_cast(aRefAttribute->attr()); + FeaturePtr anAttributeFeature = ModelAPI_Feature::feature(aPointAttr->owner()); + isSkippedAttribute = aSourceFeature == anAttributeFeature; } } - if (aPointAttr.get()) { - theAttributes.insert(aPointAttr); + } + if (isSkippedAttribute) + continue; + + // it searches the first point of AttributeRefAtt + std::shared_ptr aPointAttr; + for(anIter = anAttributes.begin(); anIter != aLast && !aPointAttr.get(); anIter++) { + AttributeRefAttrPtr aRefAttribute = + std::dynamic_pointer_cast(*anIter); + if (aRefAttribute.get()) { + aPointAttr = getPointOfRefAttr(aRefFeature.get(), aRefAttribute->id(), + theObjectFeatureKind, theObjectFeatureAttribute); } } + if (aPointAttr.get()) { + theAttributes.insert(aPointAttr); + } + } + } + // find by results + FeaturePtr aFeature = std::dynamic_pointer_cast(theObject); + if (aFeature.get()) { + const std::list > aResults = aFeature->results(); + std::list >::const_iterator aRIter = aResults.begin(); + for (; aRIter != aResults.cend(); aRIter++) { + ResultPtr aResult = *aRIter; + getPointsOfReference(aResult, theReferenceFeatureKind, theAttributes, theObjectFeatureKind, + theObjectFeatureAttribute); + } + } +} + +void appendPoint(const std::shared_ptr& thePoint, + const std::shared_ptr& theResult, + ModelGeomAlgo_Point2D::PointToRefsMap& thePointToAttributeOrObject) +{ + bool aPointFound = false; + FeaturePtr aPointFeature = ModelAPI_Feature::feature(theResult); + // check if the given point is already in the container in attribute list + for (ModelGeomAlgo_Point2D::PointToRefsMap::const_iterator + anIt = thePointToAttributeOrObject.begin(); + anIt != thePointToAttributeOrObject.end() && !aPointFound; anIt++) { + std::shared_ptr aPoint = anIt->first; + if (aPoint->isEqual(thePoint)) { + std::list > anAttributes = anIt->second.first; + for (std::list::const_iterator anAttrIt = anAttributes.begin(); + anAttrIt != anAttributes.end() && !aPointFound; anAttrIt++) { + AttributePtr anAttribute = *anAttrIt; + aPointFound = ModelAPI_Feature::feature(anAttribute->owner()) == aPointFeature; + } + } + } + + if (!aPointFound) { + if (thePointToAttributeOrObject.find(thePoint) != thePointToAttributeOrObject.end()) + thePointToAttributeOrObject.at(thePoint).second.push_back(theResult); + else { + std::list > anAttributes; + std::list > anObjects; + anObjects.push_back(theResult); + thePointToAttributeOrObject[thePoint] = std::make_pair(anAttributes, anObjects); } - // find by results - FeaturePtr aFeature = std::dynamic_pointer_cast(theObject); +#ifdef DEBUG_POINT_INSIDE_SHAPE + std::cout << "["<< thePoint->x() << ", " << thePoint->y() << "," << thePoint->z() << "]"; +#endif + } +} + +void appendShapePoints(const GeomShapePtr& theShape, + const std::shared_ptr& theResult, + ModelGeomAlgo_Point2D::PointToRefsMap& thePointToAttributeOrObject) +{ + if (!theShape.get()) + return; + + switch (theShape->shapeType()) { + case GeomAPI_Shape::VERTEX: { + std::shared_ptr aVertex = + std::shared_ptr(new GeomAPI_Vertex(theShape)); + std::shared_ptr aPnt = aVertex->point(); + appendPoint(aPnt, theResult, thePointToAttributeOrObject); + } + break; + case GeomAPI_Shape::EDGE: { + std::shared_ptr anEdge = + std::shared_ptr(new GeomAPI_Edge(theShape)); + appendPoint(anEdge->firstPoint(), theResult, thePointToAttributeOrObject); + appendPoint(anEdge->lastPoint(), theResult, thePointToAttributeOrObject); + } + break; + case GeomAPI_Shape::COMPOUND: { + for(GeomAPI_ShapeIterator anIt(theShape); anIt.more(); anIt.next()) { + appendShapePoints(anIt.current(), theResult, thePointToAttributeOrObject); + } + } + break; + default: break; + } +} + +void ModelGeomAlgo_Point2D::getPointsIntersectedShape( + const std::shared_ptr& theBaseFeature, + const std::list >& theFeatures, + PointToRefsMap& thePointToAttributeOrObject) +{ +#ifdef DEBUG_POINT_INSIDE_SHAPE + std::cout << "ModelGeomAlgo_Point2D::getPointsIntersectedShape" << std::endl; +#endif + GeomShapePtr aFeatureShape; + { + std::set anEdgeShapes; + ModelGeomAlgo_Shape::shapesOfType(theBaseFeature, GeomAPI_Shape::EDGE, anEdgeShapes); + if (anEdgeShapes.empty()) + return; + aFeatureShape = (*anEdgeShapes.begin())->shape(); + } + + std::list >::const_iterator anIt = theFeatures.begin(), + aLast = theFeatures.end(); + for (; anIt != aLast; anIt++) { + FeaturePtr aFeature = *anIt; + if (aFeature.get() == theBaseFeature.get()) + continue; if (aFeature.get()) { - const std::list > aResults = aFeature->results(); - std::list >::const_iterator aRIter = aResults.begin(); - for (; aRIter != aResults.cend(); aRIter++) { - ResultPtr aResult = *aRIter; - getPointsOfReference(aResult, theReferenceFeatureKind, theAttributes, theObjectFeatureKind, - theObjectFeatureAttribute); + std::set anEdgeShapes; + ModelGeomAlgo_Shape::shapesOfType(aFeature, GeomAPI_Shape::EDGE, anEdgeShapes); + if (anEdgeShapes.empty()) + ModelGeomAlgo_Shape::shapesOfType(aFeature, GeomAPI_Shape::VERTEX, anEdgeShapes); + + if (anEdgeShapes.empty()) + continue; + ResultPtr aResult = *anEdgeShapes.begin(); + GeomShapePtr aShape = aResult->shape(); + + GeomShapePtr aShapeOfIntersection = aFeatureShape->intersect(aShape); +#ifdef DEBUG_POINT_INSIDE_SHAPE + int aPrevSize = thePointToAttributeOrObject.size(); +#endif + appendShapePoints(aShapeOfIntersection, aResult, thePointToAttributeOrObject); +#ifdef DEBUG_POINT_INSIDE_SHAPE + if (aPrevSize != thePointToAttributeOrObject.size()) + std::cout << " <- appendShapePoints" + << thePointToAttributeOrObject.size() - aPrevSize << std::endl; +#endif + } + } +} + +std::list > ModelGeomAlgo_Point2D::getSetOfPntIntersectedShape( + const std::shared_ptr& theBaseFeature, + const std::list >& theFeatures) +{ + std::list > aPoints; + + PointToRefsMap aRefsMap; + getPointsIntersectedShape(theBaseFeature, theFeatures, aRefsMap); + + for (PointToRefsMap::const_iterator aPointIt = aRefsMap.begin(); + aPointIt != aRefsMap.end(); aPointIt++) + aPoints.push_back(aPointIt->first); + + return aPoints; +} + +void ModelGeomAlgo_Point2D::getPointsInsideShape( + const std::shared_ptr theBaseShape, + const std::set >& theAttributes, + const std::shared_ptr& theOrigin, + const std::shared_ptr& theDirX, + const std::shared_ptr& theDirY, + PointToRefsMap& thePointToAttributeOrObject) +{ +#ifdef DEBUG_POINT_INSIDE_SHAPE + std::cout << "ModelGeomAlgo_Point2D::getPointsInsideShape:" << std::endl; +#endif + std::set >::const_iterator anIt = theAttributes.begin(), + aLast = theAttributes.end(); + for (; anIt != aLast; anIt++) { + std::shared_ptr anAttribute = *anIt; + std::shared_ptr aPnt2d = anAttribute->pnt(); + std::shared_ptr aPoint = aPnt2d->to3D(theOrigin, theDirX, theDirY); + std::shared_ptr aProjectedPoint; + if (isInnerPointOnEdge(theBaseShape, aPoint, aProjectedPoint)) { + if (thePointToAttributeOrObject.find(aProjectedPoint) != thePointToAttributeOrObject.end()) + thePointToAttributeOrObject.at(aProjectedPoint).first.push_back(anAttribute); + else { + std::list > anAttributes; + std::list > anObjects; + anAttributes.push_back(anAttribute); + thePointToAttributeOrObject[aProjectedPoint] = std::make_pair(anAttributes, anObjects); } +#ifdef DEBUG_POINT_INSIDE_SHAPE + std::cout << " " << anAttribute->owner()->data()->name() << ": " << anAttribute->id() + << "[" << aPoint->x() << ", " << aPoint->y() << ", " << aPoint->z() << "]" + << std::endl; +#endif + } + else { +#ifdef DEBUG_POINT_INSIDE_SHAPE + std::cout << " " << anAttribute->owner()->data()->name() << ": " << anAttribute->id() + << "OUT of shape" << std::endl; +#endif } } +} - void getPointsInsideShape(const std::shared_ptr theBaseShape, +void ModelGeomAlgo_Point2D::getPointsInsideShape_p( + const std::shared_ptr theBaseShape, const std::set >& theAttributes, const std::shared_ptr& theOrigin, const std::shared_ptr& theDirX, @@ -127,92 +328,110 @@ namespace ModelGeomAlgo_Point2D { std::list >& thePoints, std::map, std::shared_ptr >& theAttributeToPoint) - { - std::set >::const_iterator anIt = theAttributes.begin(), - aLast = theAttributes.end(); - for (; anIt != aLast; anIt++) { - std::shared_ptr anAttribute = *anIt; - std::shared_ptr aPnt2d = anAttribute->pnt(); - std::shared_ptr aPoint = aPnt2d->to3D(theOrigin, theDirX, theDirY); - std::shared_ptr aProjectedPoint; - if (isPointOnEdge(theBaseShape, aPoint, aProjectedPoint)) { - thePoints.push_back(aProjectedPoint); - theAttributeToPoint[anAttribute] = aProjectedPoint; - } +{ + std::set >::const_iterator anIt = theAttributes.begin(), + aLast = theAttributes.end(); + for (; anIt != aLast; anIt++) { + std::shared_ptr anAttribute = *anIt; + std::shared_ptr aPnt2d = anAttribute->pnt(); + std::shared_ptr aPoint = aPnt2d->to3D(theOrigin, theDirX, theDirY); + std::shared_ptr aProjectedPoint; + if (isInnerPointOnEdge(theBaseShape, aPoint, aProjectedPoint)) { + thePoints.push_back(aProjectedPoint); + theAttributeToPoint[anAttribute] = aProjectedPoint; } } +} - bool isPointOnEdge(const std::shared_ptr theBaseShape, +bool ModelGeomAlgo_Point2D::isPointOnEdge(const std::shared_ptr theBaseShape, const std::shared_ptr& thePoint, std::shared_ptr& theProjectedPoint) - { - bool isInside = false; - if (theBaseShape->shapeType() == GeomAPI_Shape::EDGE) { - std::shared_ptr anEdge(new GeomAPI_Edge(theBaseShape)); - if (anEdge->isLine()) { - std::shared_ptr aLine = anEdge->line(); - theProjectedPoint = aLine->project(thePoint); - } - else if (anEdge->isCircle() || anEdge->isArc()) { - std::shared_ptr aCircle = anEdge->circle(); - theProjectedPoint = aCircle->project(thePoint); - } - if (theProjectedPoint.get()) { - std::shared_ptr aVertexShape(new GeomAPI_Vertex(theProjectedPoint->x(), - theProjectedPoint->y(), theProjectedPoint->z())); - isInside = GeomAlgoAPI_ShapeTools::isSubShapeInsideShape(aVertexShape, theBaseShape); - } +{ + bool isInside = false; + if (theBaseShape->shapeType() == GeomAPI_Shape::EDGE) { + GeomCurvePtr aCurve(new GeomAPI_Curve(theBaseShape->edge())); + theProjectedPoint = aCurve->project(thePoint); + if (theProjectedPoint.get()) { + std::shared_ptr aVertexShape(new GeomAPI_Vertex(theProjectedPoint->x(), + theProjectedPoint->y(), theProjectedPoint->z())); + isInside = GeomAlgoAPI_ShapeTools::isSubShapeInsideShape(aVertexShape, theBaseShape); } - return isInside; } + return isInside; +} - std::string doubleToString(double theValue) - { - std::string aValueStr; - char aBuf[50]; - int n = sprintf(aBuf, "%g", theValue); - aValueStr = std::string(aBuf); - return aValueStr; - } - std::string getPontAttributesInfo(const std::shared_ptr& theFeature, - const std::set >& theAttributesOnly) - { - std::string anInfo; - - std::list anAttrs = theFeature->data()->attributes(GeomDataAPI_Point2D::typeId()); - std::list::const_iterator anIt = anAttrs.begin(), aLast = anAttrs.end(); - - for(; anIt != aLast; anIt++) { - AttributePtr anAttribute = *anIt; - if (anAttribute.get() && (theAttributesOnly.empty() || - theAttributesOnly.find(anAttribute) != theAttributesOnly.end())) { - if (!anInfo.empty()) { - anInfo.append(", "); - anInfo.append("\n"); - } - anInfo.append(" " + getPointAttributeInfo(anAttribute)); +bool ModelGeomAlgo_Point2D::isInnerPointOnEdge(const std::shared_ptr theBaseShape, + const std::shared_ptr& thePoint, + std::shared_ptr& theProjectedPoint) +{ + bool isInside = isPointOnEdge(theBaseShape, thePoint, theProjectedPoint); + if (isInside) { + std::shared_ptr anEdge(new GeomAPI_Edge(theBaseShape)); + if (!anEdge->isClosed()) { + // check the point is not on the boundary + GeomVertexPtr aVertex(new GeomAPI_Vertex(theProjectedPoint->x(), + theProjectedPoint->y(), theProjectedPoint->z())); + GeomAPI_ShapeExplorer anExp(anEdge, GeomAPI_Shape::VERTEX); + for (; anExp.more(); anExp.next()) { + GeomVertexPtr aCurV = anExp.current()->vertex(); + isInside = !GeomAlgoAPI_ShapeTools::isSubShapeInsideShape(aVertex, aCurV); } } - return anInfo; } + return isInside; +} - std::string getPointAttributeInfo(const std::shared_ptr& theAttribute) - { - std::string anInfo; - std::string aValue = "not defined"; - std::string aType = theAttribute->attributeType(); - if (aType == GeomDataAPI_Point2D::typeId()) { - std::shared_ptr aPoint = - std::dynamic_pointer_cast(theAttribute); - if (aPoint.get() && aPoint->isInitialized()) { - aValue = std::string("(" + doubleToString(aPoint->x()) + ", "+ - doubleToString(aPoint->y()) + ")"); - } +std::string doubleToString(double theValue) +{ + std::string aValueStr; + char aBuf[50]; + sprintf(aBuf, "%g", theValue); + aValueStr = std::string(aBuf); + return aValueStr; +} + +#ifdef _DEBUG +std::string ModelGeomAlgo_Point2D::getPontAttributesInfo( + const std::shared_ptr& theFeature, + const std::set >& theAttributesOnly) +{ + std::string anInfo; + + std::list anAttrs = theFeature->data()->attributes( + GeomDataAPI_Point2D::typeId()); + std::list::const_iterator anIt = anAttrs.begin(), aLast = anAttrs.end(); + + for(; anIt != aLast; anIt++) { + AttributePtr anAttribute = *anIt; + if (anAttribute.get() && (theAttributesOnly.empty() || + theAttributesOnly.find(anAttribute) != theAttributesOnly.end())) { + if (!anInfo.empty()) { + anInfo.append(", "); + anInfo.append("\n"); } - anInfo.append(theAttribute->id() + ": " + aValue); + anInfo.append(" " + getPointAttributeInfo(anAttribute)); + } + } + return anInfo; +} - return anInfo; +std::string ModelGeomAlgo_Point2D::getPointAttributeInfo( + const std::shared_ptr& theAttribute) +{ + std::string anInfo; + std::string aValue = "not defined"; + std::string aType = theAttribute->attributeType(); + if (aType == GeomDataAPI_Point2D::typeId()) { + std::shared_ptr aPoint = + std::dynamic_pointer_cast(theAttribute); + if (aPoint.get() && aPoint->isInitialized()) { + aValue = std::string("(" + doubleToString(aPoint->x()) + ", "+ + doubleToString(aPoint->y()) + ")"); + } } + anInfo.append(theAttribute->id() + ": " + aValue); -} // namespace ModelGeomAlgo_Point2D + return anInfo; +} +#endif