+++ /dev/null
-// Copyright (C) 2016-20xx CEA/DEN, EDF R&D
-
-// File: GeomAPI_Angle.cpp
-// Created: 19 April 2016
-// Author: Artem ZHIDKOV
-
-#include <GeomAPI_Angle.h>
-#include <GeomAPI_Dir.h>
-#include <GeomAPI_Lin.h>
-#include <GeomAPI_Pnt.h>
-#include <GeomAPI_XYZ.h>
-
-#include <gp_Dir.hxx>
-#include <gp_Pnt.hxx>
-#include <gp_XYZ.hxx>
-
-/// \struct ThreePoints
-/// \brief Used to store info about angle point and state.
-struct ThreePoints {
- gp_Pnt myCenter;
- gp_Pnt myFirst;
- gp_Pnt mySecond;
- bool myReversed[2];
-};
-
-#define MY_ANGLE implPtr<ThreePoints>()
-#define PI 3.1415926535897932
-
-static ThreePoints* newAngle(const std::shared_ptr<GeomAPI_Pnt>& theCenter,
- const std::shared_ptr<GeomAPI_Pnt>& theFirst,
- const std::shared_ptr<GeomAPI_Pnt>& theSecond)
-{
- ThreePoints* aResult = new ThreePoints;
- aResult->myCenter = gp_Pnt(theCenter->x(), theCenter->y(), theCenter->z());
- aResult->myFirst = gp_Pnt(theFirst->x(), theFirst->y(), theFirst->z());
- aResult->mySecond = gp_Pnt(theSecond->x(), theSecond->y(), theSecond->z());
- aResult->myReversed[0] = aResult->myReversed[1] = false;
- return aResult;
-}
-
-static ThreePoints* newAngle(const std::shared_ptr<GeomAPI_Pnt>& theStart1,
- const std::shared_ptr<GeomAPI_Pnt>& theEnd1,
- const std::shared_ptr<GeomAPI_Pnt>& theStart2,
- const std::shared_ptr<GeomAPI_Pnt>& theEnd2)
-{
- std::shared_ptr<GeomAPI_Lin> aLine1(new GeomAPI_Lin(theStart1, theEnd1));
- std::shared_ptr<GeomAPI_Lin> aLine2(new GeomAPI_Lin(theStart2, theEnd2));
- std::shared_ptr<GeomAPI_Pnt> aCenter = aLine1->intersect(aLine2);
- bool isParallel = !aCenter;
- if (isParallel)
- aCenter = theStart1;
- std::shared_ptr<GeomAPI_Pnt> aPoint1, aPoint2;
- if (isParallel)
- aPoint1 = aPoint2 = theEnd1;
- else {
- aPoint1 = theStart1->distance(aCenter) < theEnd1->distance(aCenter) ? theEnd1 : theStart1;
- aPoint2 = theStart2->distance(aCenter) < theEnd2->distance(aCenter) ? theEnd2 : theStart2;
- }
- ThreePoints* anAngle = newAngle(aCenter, aPoint1, aPoint2);
- anAngle->myReversed[0] = aPoint1 == theStart1;
- anAngle->myReversed[1] = !isParallel && aPoint2 == theStart2;
- return anAngle;
-}
-
-static ThreePoints* newAngle(const std::shared_ptr<GeomAPI_Lin>& theLine1, bool theReversed1,
- const std::shared_ptr<GeomAPI_Lin>& theLine2, bool theReversed2)
-{
- std::shared_ptr<GeomAPI_Pnt> aCenter = theLine1->intersect(theLine2);
- if (!aCenter)
- aCenter = theLine1->location();
- double aCoeff = theReversed1 ? -1.0 : 1.0;
- std::shared_ptr<GeomAPI_Pnt> aPoint1(new GeomAPI_Pnt(
- aCenter->xyz()->added(theLine1->direction()->xyz()->multiplied(aCoeff))));
- aCoeff = theReversed2 ? -1.0 : 1.0;
- std::shared_ptr<GeomAPI_Pnt> aPoint2(new GeomAPI_Pnt(
- aCenter->xyz()->added(theLine2->direction()->xyz()->multiplied(aCoeff))));
- ThreePoints* anAngle = newAngle(aCenter, aPoint1, aPoint2);
- anAngle->myReversed[0] = theReversed1;
- anAngle->myReversed[1] = theReversed2;
- return anAngle;
-}
-
-
-
-GeomAPI_Angle::GeomAPI_Angle(const std::shared_ptr<GeomAPI_Pnt>& theStartLine1,
- const std::shared_ptr<GeomAPI_Pnt>& theEndLine1,
- const std::shared_ptr<GeomAPI_Pnt>& theStartLine2,
- const std::shared_ptr<GeomAPI_Pnt>& theEndLine2)
- : GeomAPI_Interface(newAngle(theStartLine1, theEndLine1, theStartLine2, theEndLine2))
-{
-}
-
-GeomAPI_Angle::GeomAPI_Angle(const std::shared_ptr<GeomAPI_Lin>& theLine1, bool theReversed1,
- const std::shared_ptr<GeomAPI_Lin>& theLine2, bool theReversed2)
- : GeomAPI_Interface(newAngle(theLine1, theReversed1, theLine2, theReversed2))
-{
-}
-
-GeomAPI_Angle::GeomAPI_Angle(const std::shared_ptr<GeomAPI_Pnt>& theCenter,
- const std::shared_ptr<GeomAPI_Pnt>& thePoint1,
- const std::shared_ptr<GeomAPI_Pnt>& thePoint2)
- : GeomAPI_Interface(newAngle(theCenter, thePoint1, thePoint2))
-{
-}
-
-std::shared_ptr<GeomAPI_Pnt> GeomAPI_Angle::center()
-{
- gp_Pnt aPnt = MY_ANGLE->myCenter;
- return std::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(aPnt.X(), aPnt.Y(), aPnt.Z()));
-}
-
-std::shared_ptr<GeomAPI_Pnt> GeomAPI_Angle::firstPoint()
-{
- gp_Pnt aPnt = MY_ANGLE->myFirst;
- return std::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(aPnt.X(), aPnt.Y(), aPnt.Z()));
-}
-
-std::shared_ptr<GeomAPI_Pnt> GeomAPI_Angle::secondPoint()
-{
- gp_Pnt aPnt = MY_ANGLE->mySecond;
- return std::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(aPnt.X(), aPnt.Y(), aPnt.Z()));
-}
-
-double GeomAPI_Angle::angleDegree()
-{
- return angleRadian() * 180.0 / PI;
-}
-
-double GeomAPI_Angle::angleRadian()
-{
- ThreePoints* anAngle = MY_ANGLE;
- gp_Dir aDir1(anAngle->myFirst.XYZ() - anAngle->myCenter.XYZ());
- gp_Dir aDir2(anAngle->mySecond.XYZ() - anAngle->myCenter.XYZ());
- return aDir1.Angle(aDir2);
-}
-
-bool GeomAPI_Angle::isReversed(int theIndex)
-{
- return MY_ANGLE->myReversed[theIndex & 0x1];
-}
+++ /dev/null
-// Copyright (C) 2016-20xx CEA/DEN, EDF R&D
-
-// File: GeomAPI_Angle.h
-// Created: 19 April 2016
-// Author: Artem ZHIDKOV
-
-#ifndef GeomAPI_Angle_H_
-#define GeomAPI_Angle_H_
-
-#include <GeomAPI_Interface.h>
-
-class GeomAPI_Lin;
-class GeomAPI_Pnt;
-
-/// \class GeomAPI_Angle
-/// \ingroup DataModel
-/// \brief Build an angle in 3D
-class GeomAPI_Angle : public GeomAPI_Interface
-{
-public:
- /// Creation of an angle defined by two lines' start, end points
- GEOMAPI_EXPORT
- GeomAPI_Angle(const std::shared_ptr<GeomAPI_Pnt>& theStartLine1,
- const std::shared_ptr<GeomAPI_Pnt>& theEndLine1,
- const std::shared_ptr<GeomAPI_Pnt>& theStartLine2,
- const std::shared_ptr<GeomAPI_Pnt>& theEndLine2);
- /// Creation of an angle defined by two lines taking into account their orientation
- GEOMAPI_EXPORT
- GeomAPI_Angle(const std::shared_ptr<GeomAPI_Lin>& theLine1, bool theReversed1,
- const std::shared_ptr<GeomAPI_Lin>& theLine2, bool theReversed2);
- /// Creation of an angle defined by three points
- GEOMAPI_EXPORT
- GeomAPI_Angle(const std::shared_ptr<GeomAPI_Pnt>& theCenter,
- const std::shared_ptr<GeomAPI_Pnt>& thePoint1,
- const std::shared_ptr<GeomAPI_Pnt>& thePoint2);
-
- /// Returns central point of the angle
- GEOMAPI_EXPORT std::shared_ptr<GeomAPI_Pnt> center();
- /// Returns point on the first edge
- GEOMAPI_EXPORT std::shared_ptr<GeomAPI_Pnt> firstPoint();
- /// Returns point on the second edge
- GEOMAPI_EXPORT std::shared_ptr<GeomAPI_Pnt> secondPoint();
-
- /// Returns value of the angle in degrees
- GEOMAPI_EXPORT double angleDegree();
- /// Returns value of the angle in radians
- GEOMAPI_EXPORT double angleRadian();
-
- /// Returns \c true if the line is reversed during angle calculation.
- /// If theIndex = 0, the result corresponds to the first line,
- /// if theIndex = 1, the to the second line
- GEOMAPI_EXPORT bool isReversed(int theIndex);
-};
-
-#endif
-
return theFlag;
}
+void Model_AttributeSelection::split(
+ ResultPtr theContext, TopoDS_Shape theNewShape, TopAbs_ShapeEnum theType)
+{
+ TopTools_ListOfShape aSubs;
+ for(TopoDS_Iterator anExplorer(theNewShape); anExplorer.More(); anExplorer.Next()) {
+ if (!anExplorer.Value().IsNull() &&
+ anExplorer.Value().ShapeType() == theType) {
+ aSubs.Append(anExplorer.Value());
+ } else { // invalid case; bad result shape, so, impossible to split easily
+ aSubs.Clear();
+ break;
+ }
+ }
+ if (aSubs.Extent() > 1) { // ok to split
+ TopTools_ListIteratorOfListOfShape aSub(aSubs);
+ GeomShapePtr aSubSh(new GeomAPI_Shape);
+ aSubSh->setImpl(new TopoDS_Shape(aSub.Value()));
+ setValue(theContext, aSubSh);
+ for(aSub.Next(); aSub.More(); aSub.Next()) {
+ GeomShapePtr aSubSh(new GeomAPI_Shape);
+ aSubSh->setImpl(new TopoDS_Shape(aSub.Value()));
+ myParent->append(theContext, aSubSh);
+ }
+ }
+}
+
bool Model_AttributeSelection::update()
{
TDF_Label aSelLab = selectionLabel();
// shape type shoud not not changed: if shape becomes compound of such shapes, then split
if (myParent && !anOldShape.IsNull() && !aNewShape.IsNull() &&
anOldShape.ShapeType() != aNewShape.ShapeType() &&
- aNewShape.ShapeType() == TopAbs_COMPOUND) {
- TopTools_ListOfShape aSubs;
- for(TopoDS_Iterator anExplorer(aNewShape); anExplorer.More(); anExplorer.Next()) {
- if (!anExplorer.Value().IsNull() &&
- anExplorer.Value().ShapeType() == anOldShape.ShapeType()) {
- aSubs.Append(anExplorer.Value());
- } else { // invalid case; bad result shape, so, impossible to split easily
- aSubs.Clear();
- break;
- }
- }
- if (aSubs.Extent() > 1) { // ok to split
- TopTools_ListIteratorOfListOfShape aSub(aSubs);
- GeomShapePtr aSubSh(new GeomAPI_Shape);
- aSubSh->setImpl(new TopoDS_Shape(aSub.Value()));
- setValue(aContext, aSubSh);
- for(aSub.Next(); aSub.More(); aSub.Next()) {
- GeomShapePtr aSubSh(new GeomAPI_Shape);
- aSubSh->setImpl(new TopoDS_Shape(aSub.Value()));
- myParent->append(aContext, aSubSh);
- }
- }
+ (aNewShape.ShapeType() == TopAbs_COMPOUND || aNewShape.ShapeType() == TopAbs_COMPSOLID))
+ {
+ split(aContext, aNewShape, anOldShape.ShapeType());
}
owner()->data()->sendAttributeUpdated(this); // send updated if shape is changed
}
// update scope to reset to a new one
myScope.Clear();
myRef.setValue(aModifierResFound);
+ // if context shape type is changed to more complicated and this context is selected, split
+ if (myParent &&!aSubShape.get() && aModifierResFound->shape().get() && aContext->shape().get())
+ {
+ TopoDS_Shape anOldShape = aContext->shape()->impl<TopoDS_Shape>();
+ TopoDS_Shape aNewShape = aModifierResFound->shape()->impl<TopoDS_Shape>();
+ if (!anOldShape.IsNull() && !aNewShape.IsNull() &&
+ anOldShape.ShapeType() != aNewShape.ShapeType() &&
+ (aNewShape.ShapeType() == TopAbs_COMPOUND || aNewShape.ShapeType() == TopAbs_COMPSOLID)) {
+ // prepare for split in "update"
+ TDF_Label aSelLab = selectionLabel();
+ split(aContext, aNewShape, anOldShape.ShapeType());
+ }
+ }
update(); // it must recompute a new sub-shape automatically
}
}
#include "Model_AttributeReference.h"
#include <ModelAPI_AttributeSelection.h>
#include <TDF_LabelMap.hxx>
+#include <TopoDS_Shape.hxx>
class Model_AttributeSelectionList;
/// Sets the parent attribute
void setParent(Model_AttributeSelectionList* theParent);
+ /// Splits theNewShape into sub-shapes of theType type (for the list parent of this attribute)
+ void split(ResultPtr theContext, TopoDS_Shape theNewShape, TopAbs_ShapeEnum theType);
+
friend class Model_Data;
friend class Model_AttributeSelectionList;
};