-bool SketchSolver_Builder::createEntity(
- AttributePtr theAttribute,
- std::vector<Slvs_Entity>& theEntities,
- std::vector<Slvs_Param>& theParameters)
-{
- Slvs_hEntity anEntID = theEntities.empty() ? 0 : theEntities.back().h;
- Slvs_hParam aParamID = theParameters.empty() ? 0 : theParameters.back().h;
-
- // Point in 3D
- std::shared_ptr<GeomDataAPI_Point> aPoint =
- std::dynamic_pointer_cast<GeomDataAPI_Point>(theAttribute);
- if (aPoint) {
- theParameters.push_back(Slvs_MakeParam(++aParamID, SLVS_G_UNKNOWN, aPoint->x()));
- theParameters.push_back(Slvs_MakeParam(++aParamID, SLVS_G_UNKNOWN, aPoint->y()));
- theParameters.push_back(Slvs_MakeParam(++aParamID, SLVS_G_UNKNOWN, aPoint->z()));
- theEntities.push_back(Slvs_MakePoint3d(++anEntID, SLVS_G_UNKNOWN,
- aParamID-2, aParamID-1, aParamID));
- return true;
- }
- // Point in 2D
- std::shared_ptr<GeomDataAPI_Point2D> aPoint2D =
- std::dynamic_pointer_cast<GeomDataAPI_Point2D>(theAttribute);
- if (aPoint2D) {
- theParameters.push_back(Slvs_MakeParam(++aParamID, SLVS_G_UNKNOWN, aPoint2D->x()));
- theParameters.push_back(Slvs_MakeParam(++aParamID, SLVS_G_UNKNOWN, aPoint2D->y()));
- theEntities.push_back(Slvs_MakePoint2d(++anEntID, SLVS_G_UNKNOWN, SLVS_E_UNKNOWN,
- aParamID-1, aParamID));
- return true;
- }
- // Scalar value (used for the distance entities)
- AttributeDoublePtr aScalar = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(theAttribute);
- if (aScalar) {
- theParameters.push_back(Slvs_MakeParam(++aParamID, SLVS_G_UNKNOWN, aScalar->value()));
- theEntities.push_back(Slvs_MakeDistance(++anEntID, SLVS_G_UNKNOWN,
- SLVS_E_UNKNOWN, aParamID));
- return true;
- }
- // unknown attribute type
- return false;
-}
-
-bool SketchSolver_Builder::createEntity(
- FeaturePtr theFeature,
- std::vector<Slvs_Entity>& theEntities,
- std::vector<Slvs_Param>& theParameters)
-{
- if (!theFeature->data()->isValid())
- return false;
-
- // SketchPlugin features
- std::shared_ptr<SketchPlugin_Feature> aFeature = std::dynamic_pointer_cast<
- SketchPlugin_Feature>(theFeature);
- if (!aFeature)
- return false;
-
- // Verify the feature by its kind
- const std::string& aFeatureKind = aFeature->getKind();
- DataPtr aData = aFeature->data();
- // Line
- if (aFeatureKind == SketchPlugin_Line::ID()) {
- AttributePtr aStart = aData->attribute(SketchPlugin_Line::START_ID());
- AttributePtr aEnd = aData->attribute(SketchPlugin_Line::END_ID());
- if (!aStart->isInitialized() || !aEnd->isInitialized())
- return false;
- if (!createEntity(aStart, theEntities, theParameters) ||
- !createEntity(aEnd, theEntities, theParameters))
- return false;
- Slvs_hEntity aLineID = theEntities.back().h + 1;
- theEntities.push_back(Slvs_MakeLineSegment(aLineID, SLVS_G_UNKNOWN, SLVS_E_UNKNOWN,
- aLineID-2, aLineID-1));
- }
- // Circle
- else if (aFeatureKind == SketchPlugin_Circle::ID()) {
- AttributePtr aCenter = aData->attribute(SketchPlugin_Circle::CENTER_ID());
- AttributePtr aRadius = aData->attribute(SketchPlugin_Circle::RADIUS_ID());
- if (!aCenter->isInitialized() || !aRadius->isInitialized())
- return false;
- if (!createEntity(aCenter, theEntities, theParameters) ||
- !createEntity(aRadius, theEntities, theParameters))
- return false;
- Slvs_hEntity aCircID = theEntities.back().h;
- theEntities.push_back(Slvs_MakeCircle(aCircID, SLVS_G_UNKNOWN, SLVS_E_UNKNOWN, aCircID-2,
- SLVS_E_UNKNOWN, aCircID-1));
- }
- // Arc
- else if (aFeatureKind == SketchPlugin_Arc::ID()) {
- AttributePtr aCenter = aData->attribute(SketchPlugin_Arc::CENTER_ID());
- AttributePtr aStart = aData->attribute(SketchPlugin_Arc::START_ID());
- AttributePtr aEnd = aData->attribute(SketchPlugin_Arc::END_ID());
- if (!aCenter->isInitialized() || !aStart->isInitialized() || !aEnd->isInitialized())
- return false;
- if (!createEntity(aCenter, theEntities, theParameters) ||
- !createEntity(aStart, theEntities, theParameters) ||
- !createEntity(aEnd, theEntities, theParameters))
- return false;
- Slvs_hEntity anArcID = theEntities.back().h;
- theEntities.push_back(Slvs_MakeArcOfCircle(anArcID, SLVS_G_UNKNOWN, SLVS_E_UNKNOWN,
- SLVS_E_UNKNOWN, anArcID-3, anArcID-2, anArcID-1));
- }
- // Point (it has low probability to be an attribute of constraint, so it is checked at the end)
- else if (aFeatureKind == SketchPlugin_Point::ID()) {
- AttributePtr aPoint = aData->attribute(SketchPlugin_Point::COORD_ID());
- if (!aPoint->isInitialized() ||
- !createEntity(aPoint, theEntities, theParameters))
- return false;
- // Both the sketch point and its attribute (coordinates) link to the same SolveSpace point identifier.
- // No need to add another entity.
- }
- return true;
-}
-
-bool SketchSolver_Builder::createNormal(
- AttributePtr theNormal,
- AttributePtr theDirX,
- std::vector<Slvs_Entity>& theEntities,
- std::vector<Slvs_Param>& theParameters)
-{
- std::shared_ptr<GeomDataAPI_Dir> aNorm = std::dynamic_pointer_cast<GeomDataAPI_Dir>(theNormal);
- std::shared_ptr<GeomDataAPI_Dir> aDirX = std::dynamic_pointer_cast<GeomDataAPI_Dir>(theDirX);
- if (!aDirX || (fabs(aDirX->x()) + fabs(aDirX->y()) + fabs(aDirX->z()) < tolerance) ||
- !aNorm->isInitialized())
- return false;
- // calculate Y direction
- std::shared_ptr<GeomAPI_Dir> aDirY(new GeomAPI_Dir(aNorm->dir()->cross(aDirX->dir())));
-
- // quaternion parameters of normal vector
- double qw, qx, qy, qz;
- Slvs_MakeQuaternion(aDirX->x(), aDirX->y(), aDirX->z(), aDirY->x(), aDirY->y(), aDirY->z(), &qw,
- &qx, &qy, &qz);
- double aNormCoord[4] = { qw, qx, qy, qz };
-
- // Create parameters of the normal
- Slvs_hParam aCurParam = theParameters.back().h;
- for (int i = 0; i < 4; i++)
- theParameters.push_back(Slvs_MakeParam(++aCurParam, SLVS_G_UNKNOWN, aNormCoord[i]));
-
- // Create a normal
- Slvs_hEntity aCurEntity = theEntities.back().h + 1;
- Slvs_Entity aNormal = Slvs_MakeNormal3d(aCurEntity, SLVS_G_UNKNOWN,
- aCurParam-3, aCurParam-2, aCurParam-1, aCurParam);
- theEntities.push_back(aNormal);
- return true;
-}