Add edge thickness feature. Edge thickness can be assigned to any shapes and subshapes, except vertices.
If different edge thickness values assigned both to a shape and to its subshape, subshape value overrides shape value.
Thickness data (de)serialized into xCAF and TUI.py files.
}
}
+void setEdgeThicknessValues(std::shared_ptr<ModelAPI_ResultBody> theResultBody)
+{
+ TopoDS_Shape aShape = theResultBody->shape()->impl<TopoDS_Shape>();
+ TopExp_Explorer anExp(aShape, TopAbs_SOLID); // TODO Should it be everything, except VERTEX?
+ while (anExp.More()) {
+ auto aSolid = anExp.Current();
+
+ std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape);
+ aGeomShape->setImpl(new TopoDS_Shape(aSolid));
+ auto aName = theResultBody->findShapeName(aGeomShape);
+
+ if (!aName.empty()) {
+ auto aColor = theResultBody->findShapeColor(aName); // TODO
+
+ if (!aColor.empty())
+ theResultBody->setSubShapeColor(theResultBody, aGeomShape, { 128, 222, 2 }); // TODO
+ else
+ theResultBody->setSubShapeColor(theResultBody, aGeomShape, { 255, 0, 0 }); // TODO
+
+ }
+ anExp.Next();
+ }
+}
+
//=============================================================================
std::shared_ptr<GeomAPI_Shape> setGeom(const Handle(XCAFDoc_ShapeTool) &theShapeTool,
const TDF_Label& /*theLabel*/,
std::string& theError);
GEOMALGOAPI_EXPORT void setColors(std::shared_ptr<ModelAPI_ResultBody> theResultBody);
+
+GEOMALGOAPI_EXPORT void setEdgeThicknessValues(std::shared_ptr<ModelAPI_ResultBody> theResultBody);
+
#endif /* GEOMALGOAPI_STEPIMPORTXCAF_H_ */
#include <TDF_LabelMap.hxx>
#include <TDF_CopyLabel.hxx>
#include <TDF_ListIteratorOfLabelList.hxx>
+#include <Standard_GUID.hxx>
// relocate to other file
#include <TNaming_Builder.hxx>
/// 0:1:2:N:2:K:1 - data of the K result of the feature N
/// 0:1:2:N:2:K:2:M:1 - data of the M shape of the K result of the feature N
+/*static*/ const Standard_GUID Model_Objects::GUID_EDGE_THICKNESS = Standard_GUID("9b31b32b-aaba-37c7-b8f0-58b793d81dd9");
+
Model_Objects::Model_Objects(TDF_Label theMainLab) : myMain(theMainLab)
{
}
static const Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
ModelAPI_EventCreator::get()->sendUpdated(theResult, anEvent);
}
+ else if (theAttribute->ID() == Model_Objects::GUID_EDGE_THICKNESS) {
+ Handle(TDataStd_Integer) aThicknessAttr;
+ Handle(TDataStd_Integer) anAttr = Handle(TDataStd_Integer)::DownCast(theAttribute);
+
+ if (anAttributeLabel.FindAttribute(Model_Objects::GUID_EDGE_THICKNESS, aThicknessAttr))
+ anAttributeLabel.ForgetAttribute(Model_Objects::GUID_EDGE_THICKNESS);
+
+ anAttributeLabel.AddAttribute(anAttr);
+ static const Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
+ ModelAPI_EventCreator::get()->sendUpdated(theResult, anEvent);
+ }
}
Handle(TDF_Attribute) Model_Objects::getAttribute(const Standard_GUID& theID,
ResultBodyPtr aMain = std::dynamic_pointer_cast<ModelAPI_ResultBody>(theResult);
aMain = ModelAPI_Tools::mainBody(aMain);
- int anIndex = index(theResult, theShape);
- Handle(TDataStd_IntegerArray) anColor;
+ const int anIndex = index(theResult, theShape);
+ if (anIndex == -1)
+ return opencascade::handle<TDF_Attribute>(nullptr);
+
+ TDF_Label aResultLabel;
+ if (aMain.get())
+ aResultLabel = resultLabel(theResult->data(), index(aMain));
+ else
+ aResultLabel = resultLabel(theResult->data(), index(theResult));
+
+ TDF_Label anAttributeLabel = subShapeLabel(aResultLabel, anIndex).FindChild(TAG_FEATURE_ARGUMENTS);
- if (anIndex != -1)
+ Handle(TDF_Attribute) anAttr;
+ anAttributeLabel.FindAttribute(theID, anAttr);
+ return anAttr;
+}
+
+void Model_Objects::getSubShapesWithEdgeThickness(
+ const std::shared_ptr<ModelAPI_Result> theResult,
+ std::map<std::shared_ptr<GeomAPI_Shape>, int>& oShapes
+) const {
+ ResultBodyPtr aMainBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(theResult);
+ aMainBody = ModelAPI_Tools::mainBody(aMainBody);
+ TDF_Label aShapesLabel;
+ if (aMainBody.get())
+ aShapesLabel = shapesFromResult(resultLabel(theResult->data(), index(aMainBody)));
+ else
+ aShapesLabel = shapesFromResult(resultLabel(theResult->data(), index(theResult)));
+
+ for (TDF_ChildIterator aChilds(aShapesLabel); aChilds.More(); aChilds.Next())
{
- TDF_Label aResultLabel;
- if (aMain.get())
- aResultLabel = resultLabel(theResult->data(), index(aMain));
- else
- aResultLabel = resultLabel(theResult->data(), index(theResult));
+ TDF_Label aCurSubShape = aChilds.Value();
+ Handle(TNaming_NamedShape) aNamedShape;
+ aCurSubShape.FindAttribute(TNaming_NamedShape::GetID(), aNamedShape);
+ if (aNamedShape.IsNull())
+ continue;
+
+ std::shared_ptr<GeomAPI_Shape> aSub(new GeomAPI_Shape);
+ aSub->setImpl(new TopoDS_Shape(aNamedShape->Get()));
+
+ Handle(TDataStd_Integer) aEdgeThicknessAttr;
+ aCurSubShape.FindChild(TAG_FEATURE_ARGUMENTS).FindAttribute(Model_Objects::GUID_EDGE_THICKNESS, aEdgeThicknessAttr);
+ if (aEdgeThicknessAttr.IsNull())
+ continue;
+
+ oShapes[aSub] = aEdgeThicknessAttr->Get();
+ }
+}
+
+void Model_Objects::removeSubShapeEdgeThickness(const std::shared_ptr<ModelAPI_Result> theResult) const
+{
+ ResultBodyPtr aMainBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(theResult);
+ aMainBody = ModelAPI_Tools::mainBody(aMainBody);
+
+ TDF_Label aShapesLabel;
+ if (aMainBody.get())
+ aShapesLabel = shapesFromResult(resultLabel(theResult->data(), index(aMainBody)));
+ else
+ {
+ ResultPartPtr aResPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(theResult);
+ if (!aResPart.get())
+ return;
+ aShapesLabel = shapesFromResult(resultLabel(theResult->data(), index(aResPart)));
+ }
+ for (TDF_ChildIterator aChilds(aShapesLabel); aChilds.More(); aChilds.Next())
+ {
+ TDF_Label aCurSubShape = aChilds.Value();
+ Handle(TNaming_NamedShape) aNamedShape;
+ aCurSubShape.FindAttribute(TNaming_NamedShape::GetID(), aNamedShape);
+ if (aNamedShape.IsNull())
+ continue;
- TDF_Label anAttributeLabel = subShapeLabel(aResultLabel, anIndex).FindChild(TAG_FEATURE_ARGUMENTS);
- anAttributeLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anColor);
+ aCurSubShape.FindChild(TAG_FEATURE_ARGUMENTS).ForgetAttribute(Model_Objects::GUID_EDGE_THICKNESS);
}
- return anColor;
}
void Model_Objects::getColoredShapes(const std::shared_ptr<ModelAPI_Result> theResult,
extern int kUNDEFINED_FEATURE_INDEX;
+
+class Standard_GUID;
+
+
/**\class Model_Objects
* \ingroup DataModel
* \brief Manager of objects of the document. Normally one this class corresponds to
class Model_Objects
{
public:
+ static const Standard_GUID GUID_EDGE_THICKNESS;
+
//! Registers the feature in the data structure
//! \param theFeature feature that must be added to the data structure
//! \param theAfterThis the feature will be added after this feature;
std::shared_ptr<ModelAPI_Result> theResult,
std::shared_ptr<GeomAPI_Shape> theShape);
+ void getSubShapesWithEdgeThickness(
+ const std::shared_ptr<ModelAPI_Result> theResult,
+ std::map<std::shared_ptr<GeomAPI_Shape>, int>& oShapes
+ ) const;
+
+ void removeSubShapeEdgeThickness(const std::shared_ptr<ModelAPI_Result> theResult) const;
+
//! Get colored shapes from result
void getColoredShapes(const std::shared_ptr<ModelAPI_Result> theResult,
std::map<std::shared_ptr<GeomAPI_Shape>, std::vector<int>>& theColoredShapes);
#include <TopExp_Explorer.hxx>
#include <TopTools_MapOfShape.hxx>
#include <TDataStd_UAttribute.hxx>
+#include <TDataStd_Integer.hxx>
#include <TDataStd_IntegerArray.hxx>
#include <TNaming_Tool.hxx>
#include <TDF_Reference.hxx>
}
}
+void Model_ResultBody::setSubShapeEdgeThickness(
+ const std::shared_ptr<ModelAPI_Result> theResult,
+ const std::shared_ptr<GeomAPI_Shape> theSubShape,
+ int theEdgeThickness
+)
+{
+ TopoDS_Shape aShape = shape()->impl<TopoDS_Shape>();
+ TopoDS_Shape aSubShape = theSubShape->impl<TopoDS_Shape>();
+ if (!shape()->isSubShape(theSubShape))
+ return;
+
+ Model_Objects* anObjects = std::dynamic_pointer_cast<Model_Document>(document())->objects();
+ document()->storeShape(data(), theResult, theSubShape);
+
+ Handle(TDataStd_Integer) aThickness = new TDataStd_Integer();
+ aThickness->SetID(Model_Objects::GUID_EDGE_THICKNESS);
+ aThickness->Set(theEdgeThickness);
+ anObjects->setAttribute(aThickness, theResult, theSubShape);
+}
+
+int Model_ResultBody::getSubShapeEdgeThickness(const std::shared_ptr<ModelAPI_Result> theResult, const std::shared_ptr<GeomAPI_Shape> theSubShape) const
+{
+ TopoDS_Shape aShape = shape()->impl<TopoDS_Shape>();
+ TopoDS_Shape aSubShape = theSubShape->impl<TopoDS_Shape>();
+ if (!shape()->isSubShape(theSubShape))
+ return -1;
+
+ Model_Objects* anObjects = std::dynamic_pointer_cast<Model_Document>(document())->objects();
+ auto anAttr = Handle(TDataStd_Integer)::DownCast(anObjects->getAttribute(Model_Objects::GUID_EDGE_THICKNESS, theResult, theSubShape));
+ if (anAttr.IsNull())
+ return -1;
+
+ return anAttr->Get();
+}
+
+void Model_ResultBody::getSubShapesWithEdgeThickness(
+ const std::shared_ptr<ModelAPI_Result> theResult,
+ std::map<std::shared_ptr<GeomAPI_Shape>, int>& oShapes
+) const
+{
+ Model_Objects* anObjects = std::dynamic_pointer_cast<Model_Document>(document())->objects();
+ anObjects->getSubShapesWithEdgeThickness(theResult, oShapes);
+}
+
+void Model_ResultBody::removeSubShapeEdgeThickness(const std::shared_ptr<ModelAPI_Result> theResult)
+{
+ Model_Objects* anObjects = std::dynamic_pointer_cast<Model_Document>(document())->objects();
+ anObjects->removeSubShapeEdgeThickness(theResult);
+}
+
void Model_ResultBody::addShapeColor( const std::wstring& theName,std::vector<int>& color)
{
if (myColorsShape.find(theName) == myColorsShape.end())
/// Checks the state of children and parents to send events of creation/erase when needed
void updateConcealment();
+ void setSubShapeEdgeThickness(
+ const std::shared_ptr<ModelAPI_Result> theResult,
+ const std::shared_ptr<GeomAPI_Shape> theSubShape,
+ int theEdgeThickness
+ );
+
+ int getSubShapeEdgeThickness(const std::shared_ptr<ModelAPI_Result> theResult, const std::shared_ptr<GeomAPI_Shape> theSubShape) const;
+
+ void getSubShapesWithEdgeThickness(
+ const std::shared_ptr<ModelAPI_Result> theResult,
+ std::map<std::shared_ptr<GeomAPI_Shape>, int>& oSubShapes
+ ) const;
+
+ void removeSubShapeEdgeThickness(const std::shared_ptr<ModelAPI_Result> theResult);
+
/// Adds to theOldForSub only old shapes that where used for theSub creation
void computeOldForSub(const GeomShapePtr& theSub,
const std::list<GeomShapePtr>& theAllOlds, std::list<GeomShapePtr>& theOldForSub);
#include <ModelAPI_Session.h>
#include <ModelAPI_Feature.h>
#include <ModelAPI_ResultBody.h>
+#include <ModelAPI_AttributeInteger.h>
#include <ModelAPI_AttributeIntArray.h>
#include <ModelAPI_AttributeSelectionList.h>
#include <ModelAPI_AttributeReference.h>
#include <TNaming_Tool.hxx>
#include <TNaming_NamedShape.hxx>
#include <TDataStd_Name.hxx>
+#include <TDataStd_Integer.hxx>
#include <TDataStd_IntegerArray.hxx>
#include <TopoDS_Compound.hxx>
#include <BRep_Builder.hxx>
AttributeDocRefPtr aDocRef = std::dynamic_pointer_cast<ModelAPI_AttributeDocRef>(
data()->addAttribute(DOC_REF(), ModelAPI_AttributeDocRef::typeId()));
data()->addAttribute(COLOR_ID(), ModelAPI_AttributeIntArray::typeId());
+ data()->addAttribute(EDGE_THICKNESS_ID(), ModelAPI_AttributeInteger::typeId());
data()->addAttribute(BASE_REF_ID(), ModelAPI_AttributeReference::typeId());
data()->addAttribute(DEFLECTION_ID(), ModelAPI_AttributeDouble::typeId());
data()->addAttribute(TRANSPARENCY_ID(), ModelAPI_AttributeDouble::typeId());
return aResult;
}
+void Model_ResultPart::setSubShapeEdgeThickness(const std::shared_ptr<GeomAPI_Shape>& theSubShape, int theThickness)
+{
+ TopoDS_Shape aShape = shape()->impl<TopoDS_Shape>();
+ TopoDS_Shape aSubShape = theSubShape->impl<TopoDS_Shape>();
+ if (!shape()->isSubShape(theSubShape))
+ return;
+
+ Model_Objects* anObjects = std::dynamic_pointer_cast<Model_Document>(document())->objects();
+
+ document()->storeShape(data(), original(), theSubShape);
+ Handle(TDataStd_Integer) aThickness = new TDataStd_Integer();
+ aThickness->SetID(Model_Objects::GUID_EDGE_THICKNESS);
+ aThickness->Set(theThickness);
+ anObjects->setAttribute(aThickness, original(), theSubShape);
+}
+
+int Model_ResultPart::getSubShapeEdgeThickness(const std::shared_ptr<GeomAPI_Shape>& theSubShape) const
+{
+ TopoDS_Shape aShape = shape()->impl<TopoDS_Shape>();
+ TopoDS_Shape aSubShape = theSubShape->impl<TopoDS_Shape>();
+ if (!shape()->isSubShape(theSubShape))
+ return -1;
+
+ Model_Objects* anObjects = std::dynamic_pointer_cast<Model_Document>(document())->objects();
+ Handle(TDataStd_Integer) anAttr = Handle(TDataStd_Integer)::DownCast(anObjects->getAttribute(Model_Objects::GUID_EDGE_THICKNESS, original(), theSubShape));
+ if (anAttr.IsNull())
+ return -1;
+
+ return anAttr->Get();
+}
+
+void Model_ResultPart::getSubShapesWithEdgeThickness(std::map<std::shared_ptr<GeomAPI_Shape>, int>& oShapes)
+{
+ Model_Objects* anObjects = std::dynamic_pointer_cast<Model_Document>(document())->objects();
+ anObjects->getSubShapesWithEdgeThickness(original(), oShapes);
+}
+
+void Model_ResultPart::removeSubShapeEdgeThickness()
+{
+ Model_Objects* anObjects = std::dynamic_pointer_cast<Model_Document>(document())->objects();
+ anObjects->removeSubShapeEdgeThickness(original());
+}
+
void Model_ResultPart::setSubShapeColor(const std::shared_ptr<GeomAPI_Shape>& theShape,
const std::vector<int>& theColor)
{
MODEL_EXPORT virtual bool updateInPart(const int theIndex);
/// Returns the shape by the name in the part
MODEL_EXPORT virtual std::shared_ptr<GeomAPI_Shape> shapeInPart(
- const std::wstring& theName, const std::string& theType, int& theIndex); /// Set color on subshape
+ const std::wstring& theName, const std::string& theType, int& theIndex);
+
+ MODEL_EXPORT virtual void setSubShapeEdgeThickness(const std::shared_ptr<GeomAPI_Shape>& theSubShape, int theThickness);
+
+ MODEL_EXPORT virtual int getSubShapeEdgeThickness(const std::shared_ptr<GeomAPI_Shape>& theSubShape) const;
+
+ MODEL_EXPORT virtual void getSubShapesWithEdgeThickness(std::map<std::shared_ptr<GeomAPI_Shape>, int>& oSubShapes);
+
+ MODEL_EXPORT virtual void removeSubShapeEdgeThickness();
+
+ /// Set color on subshape
MODEL_EXPORT virtual void setSubShapeColor(const std::shared_ptr<GeomAPI_Shape>& theShape,
const std::vector<int>& theColor);
#include <ModelAPI_Events.h>
#include <ModelAPI_Data.h>
#include <ModelAPI_Attribute.h>
+#include <ModelAPI_AttributeInteger.h>
#include <ModelAPI_AttributeIntArray.h>
#include <ModelAPI_AttributeDouble.h>
#include <ModelAPI_AttributeBoolean.h>
// append the color attribute. It is empty, the attribute will be filled by a request
DataPtr aData = data();
aData->addAttribute(COLOR_ID(), ModelAPI_AttributeIntArray::typeId())->setIsArgument(false);
+ aData->addAttribute(EDGE_THICKNESS_ID(), ModelAPI_AttributeInteger::typeId());
aData->addAttribute(DEFLECTION_ID(), ModelAPI_AttributeDouble::typeId())->setIsArgument(false);
aData->addAttribute(TRANSPARENCY_ID(), ModelAPI_AttributeDouble::typeId())->setIsArgument(false);
aData->addAttribute(ISO_LINES_ID(), ModelAPI_AttributeIntArray::typeId())->setIsArgument(false);
return MY_COLOR_ID;
}
+ /// Reference to the edge thickness of the result.
+ /// The integer value is used. The value is in [1, 5] range
+ inline static const std::string& EDGE_THICKNESS_ID()
+ {
+ static const std::string MY_EDGE_THICKNESS_ID("Edge_Thickness");
+ return MY_EDGE_THICKNESS_ID;
+ }
+
/// Reference to the deflection of the result.
/// The double value is used. The value is in [0, 1] range
inline static const std::string& DEFLECTION_ID()
MODELAPI_EXPORT virtual ~ModelAPI_Result();
/// Returns the shape-result produced by this feature (or null if no shapes)
- MODELAPI_EXPORT virtual std::shared_ptr<GeomAPI_Shape> shape();
+ MODELAPI_EXPORT virtual std::shared_ptr<GeomAPI_Shape> shape();
/// Returns all the vertices of this result
MODELAPI_EXPORT virtual ListOfShape
MODELAPI_EXPORT virtual std::wstring addShapeName
(std::shared_ptr<GeomAPI_Shape>, const std::wstring& theName) = 0;
+ MODELAPI_EXPORT virtual void setSubShapeEdgeThickness(
+ const std::shared_ptr<ModelAPI_Result> theResult,
+ const std::shared_ptr<GeomAPI_Shape> theSubShape,
+ int theEdgeThickness
+ ) = 0;
+
+ MODELAPI_EXPORT virtual int getSubShapeEdgeThickness(
+ const std::shared_ptr<ModelAPI_Result> theResult,
+ const std::shared_ptr<GeomAPI_Shape> theSubShape
+ ) const = 0;
+
+ MODELAPI_EXPORT virtual void getSubShapesWithEdgeThickness(
+ const std::shared_ptr<ModelAPI_Result> theResult,
+ std::map<std::shared_ptr<GeomAPI_Shape>, int>& oSubShapes
+ ) const = 0;
+
+ MODELAPI_EXPORT virtual void removeSubShapeEdgeThickness(const std::shared_ptr<ModelAPI_Result> theResult) = 0;
+
/// Add color for shape Name read shape in step file
MODELAPI_EXPORT virtual void addShapeColor
(const std::wstring& theName, std::vector<int>& theColor) = 0;
/// Returns the shape by the name in the part
virtual std::shared_ptr<GeomAPI_Shape> shapeInPart(
const std::wstring& theName, const std::string& theType, int& theIndex) = 0;
+
+ virtual void setSubShapeEdgeThickness(const std::shared_ptr<GeomAPI_Shape>& theSubShape, int theThickness) = 0;
+
+ virtual int getSubShapeEdgeThickness(const std::shared_ptr<GeomAPI_Shape>& theSubShape) const = 0;
+
+ virtual void getSubShapesWithEdgeThickness(std::map<std::shared_ptr<GeomAPI_Shape>, int>& oSubShapes) = 0;
+
+ virtual void removeSubShapeEdgeThickness() = 0;
+
/// Set color on subshape
virtual void setSubShapeColor(const std::shared_ptr<GeomAPI_Shape>& theShape,
const std::vector<int>& theColor) = 0;
Config_PropManager::registerProp("Visualization", "shaper_default_transparency",
"Default transparency (%)", Config_Prop::IntSpin, "0", "0", "100");
+ Config_PropManager::registerProp("Visualization", "shaper_default_edge_thickness",
+ "Default edge thickness (pt)", Config_Prop::IntSpin, "3", "1", "5");
+
}
return MY_MANAGER;
}
#include <ModelAPI_AttributeDocRef.h>
#include <ModelAPI_AttributeDouble.h>
#include <ModelAPI_AttributeImage.h>
+#include <ModelAPI_AttributeInteger.h>
#include <ModelAPI_AttributeIntArray.h>
#include <ModelAPI_AttributeSelectionList.h>
#include <ModelAPI_CompositeFeature.h>
}
+//**************************************************************
+int getEdgeThickness(const std::shared_ptr<ModelAPI_Result>& theResult)
+{
+ int aThickness = -1;
+ if (theResult && theResult->data()->attribute(ModelAPI_Result::EDGE_THICKNESS_ID())) {
+ AttributeIntegerPtr aIntAttr = theResult->data()->integer(ModelAPI_Result::EDGE_THICKNESS_ID());
+ if (aIntAttr && aIntAttr->isInitialized())
+ aThickness = aIntAttr->value();
+ }
+ return aThickness;
+}
+
+int getSubShapeEdgeThickness(const std::shared_ptr<ModelAPI_Result> theResult, const std::shared_ptr<GeomAPI_Shape> theSubShape)
+{
+ if (!theResult || theSubShape->isNull())
+ return -1;
+
+ if (!theResult->shape()->isSubShape(theSubShape))
+ return -1;
+
+ auto resultBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(theResult);
+ if (resultBody) {
+ resultBody = mainBody(resultBody);
+ return resultBody->getSubShapeEdgeThickness(theResult, theSubShape);
+ }
+ else {
+ const auto resultPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(theResult);
+ if (!resultPart)
+ return -1;
+
+ return resultPart->getSubShapeEdgeThickness(theSubShape);
+ }
+}
+
+void getSubShapesWithEdgeThickness(
+ const std::shared_ptr<ModelAPI_Result> theResult,
+ std::map<std::shared_ptr<GeomAPI_Shape>, int>& oShapes,
+ bool theGetSubResults
+) {
+ if (!theResult)
+ return;
+
+ const auto resultBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(theResult);
+ if (resultBody) {
+ ResultBodyPtr mainBody = ModelAPI_Tools::mainBody(resultBody);
+ if (!mainBody)
+ return;
+
+ if (theGetSubResults) {
+ std::list<ResultPtr> subResults;
+ allSubs(resultBody, subResults);
+ for (auto itSubRes = subResults.begin(); itSubRes != subResults.end(); ++itSubRes) {
+ mainBody->getSubShapesWithEdgeThickness(*itSubRes, oShapes);
+ }
+ }
+
+ mainBody->getSubShapesWithEdgeThickness(theResult, oShapes);
+ }
+ else {
+ const auto resultPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(theResult);
+ if (!resultPart)
+ return;
+
+ resultPart->getSubShapesWithEdgeThickness(oShapes);
+ }
+}
+
+void removeSubShapeEdgeThickness(const std::shared_ptr<ModelAPI_Result> theResult)
+{
+ if (!theResult)
+ return;
+
+ auto resultBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(theResult);
+ if (resultBody) {
+ resultBody = mainBody(resultBody);
+ resultBody->removeSubShapeEdgeThickness(theResult);
+ }
+ else {
+ auto resultPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(theResult);
+ if (!resultPart)
+ return;
+
+ resultPart->removeSubShapeEdgeThickness();
+ }
+}
+
+void setEdgeThickness(std::shared_ptr<ModelAPI_Result> theResult, int theEdgeThickness)
+{
+ if (!theResult)
+ return;
+
+ const AttributeIntegerPtr anAttribute = theResult->data()->integer(ModelAPI_Result::EDGE_THICKNESS_ID());
+ if (anAttribute) {
+ anAttribute->setValue(theEdgeThickness);
+ removeSubShapeEdgeThickness(theResult);
+ }
+}
+
+void setSubShapeEdgeThickness(
+ std::shared_ptr<ModelAPI_Result> theResult,
+ std::shared_ptr<GeomAPI_Shape> theSubShape,
+ int theEdgeThickness
+) {
+ if (!theResult || theSubShape->isNull())
+ return;
+
+ if (!theResult->shape()->isSubShape(theSubShape))
+ return;
+
+ auto resultBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(theResult);
+ if (resultBody) {
+ resultBody = mainBody(resultBody);
+ resultBody->setSubShapeEdgeThickness(theResult, theSubShape, theEdgeThickness);
+ }
+ else {
+ const auto resultPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(theResult);
+ if (!resultPart)
+ return;
+
+ resultPart->setSubShapeEdgeThickness(theSubShape, theEdgeThickness);
+ }
+
+ static const Events_ID EVENT = Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY);
+ ModelAPI_EventCreator::get()->sendUpdated(theResult, EVENT);
+}
+
+
+//**************************************************************
void getColor(const std::shared_ptr<ModelAPI_Result>& theResult, std::vector<int>& theColor)
{
theColor.clear();
MODELAPI_EXPORT void setDeflection(std::shared_ptr<ModelAPI_Result> theResult,
const double theDeflection);
+/*! \returns -1, if edge thickness is not defined. */
+MODELAPI_EXPORT int getEdgeThickness(const std::shared_ptr<ModelAPI_Result>& theResult);
+
+/*! \returns -1, if edge thickness is not defined. */
+MODELAPI_EXPORT int getSubShapeEdgeThickness(const std::shared_ptr<ModelAPI_Result> theResult, const std::shared_ptr<GeomAPI_Shape> theSubShape);
+
+/*! \returns theResult subshapes with defined edge thickness.
+* \param theSubResults - true, to include subshapes of subresults. */
+MODELAPI_EXPORT void getSubShapesWithEdgeThickness(
+ const std::shared_ptr<ModelAPI_Result> theResult,
+ std::map<std::shared_ptr<GeomAPI_Shape>,int>& oShapes,
+ bool theGetSubResults = false
+);
+
+/*! \brief Removes edge thickness data of result subshapes. */
+MODELAPI_EXPORT void removeSubShapeEdgeThickness(const std::shared_ptr<ModelAPI_Result> theResult);
+
+MODELAPI_EXPORT void setEdgeThickness(std::shared_ptr<ModelAPI_Result> theResult, int theEdgeThickness);
+
+/*! \param theShape belongs to theResult. */
+MODELAPI_EXPORT void setSubShapeEdgeThickness(
+ std::shared_ptr<ModelAPI_Result> theResult,
+ std::shared_ptr<GeomAPI_Shape> theSubShape,
+ int theEdgeThickness
+);
+
/*! Returns current color of the current result
* \param[in] theResult a result object
* \param[out] theColor a color values if it is defined
anEntityNames.myUserName.clear();
anEntityNames.myIsDefault = true;
}
+
+ // Set result edge thickness.
+ if (isEdgeThicknessDefined(*aResIt)) {
+ AttributeIntegerPtr attrThickness = (*aResIt)->data()->integer(ModelAPI_Result::EDGE_THICKNESS_ID());
+ if (attrThickness && attrThickness->isInitialized()) {
+ *this << *aResIt;
+ *myDumpStorage << ".setEdgeThickness(" << attrThickness->value() << ")\n";
+ }
+ }
+ // Set subresult edge thickness.
+ std::map<GeomShapePtr, int> aShapesWithEdgeThickness;
+ ModelAPI_Tools::getSubShapesWithEdgeThickness(*aResIt, aShapesWithEdgeThickness, true /*theGetSubResults*/);
+
+ if ((isParentResult(*aResIt)) && !aShapesWithEdgeThickness.empty()) {
+ for (const auto& shapeAndThickness : aShapesWithEdgeThickness) {
+ const GeomShapePtr& aShape = shapeAndThickness.first;
+
+ *this << *aResIt;
+ *myDumpStorage << ".setEdgeThickness(model.selection(\"" << aShape->shapeTypeStr() << "\", \""
+ << Locale::Convert::toString((*aResIt)->data()->name(aShape)) << "\"), "
+ << shapeAndThickness.second << ")\n";
+ }
+ }
+
// set result color
if (!isDefaultColor(*aResIt)) {
AttributeIntArrayPtr aColor = (*aResIt)->data()->intArray(ModelAPI_Result::COLOR_ID());
return anOwner && anOwner->getKind() == SKETCH;
}
+bool ModelHighAPI_Dumper::hasShapeWithEdgeThickness(const ResultPtr& theResult, bool theGetSubResults = false) const
+{
+ std::map<GeomShapePtr, int> aShapes;
+ ModelAPI_Tools::getSubShapesWithEdgeThickness(theResult, aShapes, theGetSubResults);
+ return !aShapes.empty();
+}
+
bool ModelHighAPI_Dumper::hasColoredShape(const ResultPtr& theResult, bool theGetSubResults) const
{
std::map<GeomShapePtr, std::vector<int>> aColoredShapes;
return false;
}
+bool ModelHighAPI_Dumper::isEdgeThicknessDefined(const ResultPtr& theResult) const
+{
+ const auto anAttribute = theResult->data()->integer(ModelAPI_Result::EDGE_THICKNESS_ID());
+ if (!anAttribute || !anAttribute->isInitialized())
+ return false;
+
+ // Do not dump edge thickness, if theResult belongs to sketch entity.
+ const auto aResConstr = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(theResult);
+ if (aResConstr) {
+ FeaturePtr aFeature = ModelAPI_Feature::feature(theResult->data()->owner());
+ if (isSketchSub(aFeature))
+ return false;
+ }
+
+ return true;
+}
+
bool ModelHighAPI_Dumper::isDefaultColor(const ResultPtr& theResult) const
{
AttributeIntArrayPtr aColor = theResult->data()->intArray(ModelAPI_Result::COLOR_ID());
if (!myNames[theEntity].myIsDumped) {
bool isUserDefinedName = !myNames[theEntity].myIsDefault;
- // store results if they have user-defined names or colors
- std::list<ResultPtr> aResultsWithNameOrColor;
+ // Store results if they have user-defined names, colors or edge thickness.
+ std::list<ResultPtr> aResultsWithNonDefaultAttr;
std::list<ResultPtr> allRes;
ModelAPI_Tools::allResults(theEntity, allRes);
- for(std::list<ResultPtr>::iterator aRes = allRes.begin(); aRes != allRes.end(); aRes++) {
- if(!myNames[*aRes].myIsDefault || !isDefaultColor(*aRes) ||
- !isDefaultDeflection(*aRes) || !isDefaultTransparency(*aRes) ||
- (isParentResult(*aRes) && hasColoredShape(*aRes, true)))
- aResultsWithNameOrColor.push_back(*aRes);
+ for (const auto& aRes : allRes) {
+ if (!myNames[aRes].myIsDefault || !isDefaultColor(aRes) || isEdgeThicknessDefined(aRes) ||
+ !isDefaultDeflection(aRes) || !isDefaultTransparency(aRes) ||
+ (isParentResult(aRes) && (hasColoredShape(aRes, true) || hasShapeWithEdgeThickness(aRes, true))))
+ aResultsWithNonDefaultAttr.push_back(aRes);
}
+
// store just dumped entity to stack
if (myEntitiesStack.empty() || myEntitiesStack.top().myEntity != theEntity)
- myEntitiesStack.push(
- LastDumpedEntity(theEntity, isUserDefinedName, aResultsWithNameOrColor));
+ myEntitiesStack.push(LastDumpedEntity(theEntity, isUserDefinedName, aResultsWithNonDefaultAttr));
}
// remove entity from the list of not dumped items
/// Stores names of results for the given feature
void saveResultNames(const FeaturePtr& theFeature);
+ bool hasShapeWithEdgeThickness(const ResultPtr& theResult, bool theGetSubResults = false) const;
+
/// Check the result feature has colored shape
bool hasColoredShape(const ResultPtr& theResult, bool theGetSubResults = false) const;
/// Check the result is parent result int the feature
bool isParentResult(const ResultPtr& theResult) const;
+ /// Check the result feature has edge thickness attribute
+ bool isEdgeThicknessDefined(const ResultPtr& theResult) const;
+
/// Check the result feature has default color
bool isDefaultColor(const ResultPtr& theResult) const;
#include "ModelHighAPI_Selection.h"
#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeInteger.h>
#include <ModelAPI_AttributeIntArray.h>
#include <ModelAPI_AttributeSelection.h>
#include <ModelAPI_AttributeSelectionList.h>
return std::wstring();
}
+void ModelHighAPI_Selection::setEdgeThickness(int theValue)
+{
+ if (myVariantType != VT_ResultSubShapePair || !myResultSubShapePair.first.get())
+ return;
+
+ const auto attr = myResultSubShapePair.first->data()->integer(ModelAPI_Result::EDGE_THICKNESS_ID());
+ attr->setValue(theValue);
+}
+
+void ModelHighAPI_Selection::setEdgeThickness(const ModelHighAPI_Selection& theShape, int theValue)
+{
+ if (myVariantType != VT_ResultSubShapePair || !myResultSubShapePair.first.get())
+ return;
+
+ std::shared_ptr<GeomAPI_Shape> aShape = myResultSubShapePair.second;
+ ResultBodyPtr aResBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(myResultSubShapePair.first);
+
+ ResultPtr aRes;
+ AttributeSelectionPtr aSelAttr;
+ if (aResBody.get())
+ {
+ aSelAttr = aResBody->selection();
+ theShape.fillAttribute(aSelAttr);
+ }
+ else
+ {
+ std::wstring aSubShapeName = theShape.myTypeSubShapeNamePair.second;
+ aSubShapeName = changePartName(theShape, aSubShapeName);
+ ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(myResultSubShapePair.first);
+ aSelAttr = aPart->selection();
+ aSelAttr->selectSubShape(myTypeSubShapeNamePair.first, aSubShapeName);
+ }
+ aRes = aSelAttr->context();
+ aShape = aSelAttr->value();
+ if (aRes.get() && aShape.get() && !aShape->isNull())
+ ModelAPI_Tools::setSubShapeEdgeThickness(aRes, aShape, theValue);
+}
+
void ModelHighAPI_Selection::setColor(int theRed, int theGreen, int theBlue, bool random)
{
if (myVariantType != VT_ResultSubShapePair || !myResultSubShapePair.first.get())
MODELHIGHAPI_EXPORT
std::wstring name() const;
+ /// Change edge thickness of result
+ MODELHIGHAPI_EXPORT
+ void setEdgeThickness(int theValue);
+
+ /// Change edge thickness of subshape.
+ MODELHIGHAPI_EXPORT
+ void setEdgeThickness(const ModelHighAPI_Selection& theShape, int theValue);
+
/// Change result's color
MODELHIGHAPI_EXPORT
void setColor(int theRed = 0, int theGreen = 0, int theBlue = 0, bool random = false);
Config_PropManager::registerProp("Visualization", "axis_arrow_size",
"Trihedron arrows constant size", Config_Prop::IntSpin, "10");
+ Config_PropManager::registerProp("Visualization", "result_subshape_with_edge_thickness",
+ "Set edge thickness of subshape of result", Config_Prop::Boolean, "true");
+
Config_PropManager::registerProp("Visualization", "color_subshape_result",
"Set color on subshape of result", Config_Prop::Boolean, "true");
- Config_PropManager::registerProp("Shortcuts", "add_parameter_shortcut",
- "Add parameter in parameters manager dialog",
- Config_Prop::Shortcut, "Ctrl+A");
-
Config_PropManager::registerProp("Windows", "use_hide_faces_panel",
"Use HideFaces panel in operations", Config_Prop::Boolean, "false");
}
}
+int PartSet_Tools::getDefaultEdgeThickness()
+{
+ return Config_PropManager::integer("Visualization", "shaper_default_edge_thickness");
+}
+
+
void PartSet_Tools::getDefaultColor(ObjectPtr theObject, const bool isEmptyColorValid,
std::vector<int>& theColor)
{
static void getFirstAndLastIndexInFolder(const ObjectPtr& theFolder,
int& theFirst, int& theLast);
+ /**
+ * Returns user-defined default edge thickness value
+ */
+ static int getDefaultEdgeThickness();
/**
* Returns default color value for the given object
<parameter name="scalar_bar_nb_intervals" value="20" />
<parameter name="scalar_bar_text_color" value="#000000" />
<parameter name="shaper_default_transparency" value="0"/>
+ <parameter name="shaper_default_edge_thickness" value="3"/>
<parameter name="group_names_display" value="true" />
<parameter name="group_names_font" value="Times-bold" />
<parameter name="group_names_size" value="12" />
XGUI_DataModel.h
XGUI_DeflectionDialog.h
XGUI_Displayer.h
+ XGUI_EdgeThicknessWidget.h
XGUI_ErrorDialog.h
XGUI_ErrorMgr.h
XGUI_FacesPanel.h
XGUI_DataModel.h
XGUI_DeflectionDialog.h
XGUI_Displayer.h
+ XGUI_EdgeThicknessWidget.h
XGUI_ErrorDialog.h
XGUI_ErrorMgr.h
XGUI_FacesPanel.h
XGUI_DataModel.cpp
XGUI_DeflectionDialog.cpp
XGUI_Displayer.cpp
+ XGUI_EdgeThicknessWidget.cpp
XGUI_ErrorDialog.cpp
XGUI_ErrorMgr.cpp
XGUI_FacesPanel.cpp
tr("Transparency..."), aDesktop);
addAction("TRANSPARENCY_CMD", anAction);
+ anAction = ModuleBase_Tools::createAction(QIcon(), tr("Edge Thickness..."), aDesktop);
+ addAction("EDGE_THICKNESS_CMD", anAction);
+
anAction = ModuleBase_Tools::createAction(QIcon(":pictures/eye_pencil.png"),
tr("Show"), aDesktop);
addAction("SHOW_CMD", anAction);
action("COLOR_CMD")->setEnabled(myWorkshop->canChangeProperty("COLOR_CMD"));
action("DEFLECTION_CMD")->setEnabled(myWorkshop->canChangeProperty("DEFLECTION_CMD"));
action("TRANSPARENCY_CMD")->setEnabled(myWorkshop->canChangeProperty("TRANSPARENCY_CMD"));
+ action("EDGE_THICKNESS_CMD")->setEnabled(myWorkshop->canChangeProperty("EDGE_THICKNESS_CMD"));
action("AUTOCOLOR_CMD")->setEnabled(myWorkshop->canChangeProperty("AUTOCOLOR_CMD"));
#ifdef _DEBUG
if (myWorkshop->canChangeProperty("TRANSPARENCY_CMD"))
action("TRANSPARENCY_CMD")->setEnabled(true);
+ if (myWorkshop->canChangeProperty("EDGE_THICKNESS_CMD"))
+ action("EDGE_THICKNESS_CMD")->setEnabled(true);
+
action("DELETE_CMD")->setEnabled(true);
}
aList.append(action("COLOR_CMD"));
aList.append(action("DEFLECTION_CMD"));
aList.append(action("TRANSPARENCY_CMD"));
+ aList.append(action("EDGE_THICKNESS_CMD"));
aList.append(action("SHOW_FEATURE_CMD"));
aList.append(mySeparator2);
aList.append(action("DELETE_CMD"));
aList.append(action("COLOR_CMD"));
aList.append(action("DEFLECTION_CMD"));
aList.append(action("TRANSPARENCY_CMD"));
+ aList.append(action("EDGE_THICKNESS_CMD"));
aList.append(action("SHOW_ISOLINES_CMD"));
aList.append(action("ISOLINES_CMD"));
aList.append(action("SHOW_FEATURE_CMD"));
aList.append(action("COLOR_CMD"));
aList.append(action("DEFLECTION_CMD"));
aList.append(action("TRANSPARENCY_CMD"));
+ aList.append(action("EDGE_THICKNESS_CMD"));
aList.append(action("SHOW_ISOLINES_CMD"));
aList.append(action("ISOLINES_CMD"));
aList.append(action("SHOW_FEATURE_CMD"));
aList.append(action("COLOR_CMD"));
aList.append(action("DEFLECTION_CMD"));
aList.append(action("TRANSPARENCY_CMD"));
+ aList.append(action("EDGE_THICKNESS_CMD"));
aList.append(mySeparator3);
aList.append(action("SET_VIEW_NORMAL_CMD"));
aList.append(action("SET_VIEW_INVERTEDNORMAL_CMD"));
aList.append(action("COLOR_CMD"));
aList.append(action("DEFLECTION_CMD"));
aList.append(action("TRANSPARENCY_CMD"));
+ aList.append(action("EDGE_THICKNESS_CMD"));
aList.append(action("SHOW_ISOLINES_CMD"));
aList.append(action("ISOLINES_CMD"));
aList.append(mySeparator3);
aList.append(action("COLOR_CMD"));
aList.append(action("DEFLECTION_CMD"));
aList.append(action("TRANSPARENCY_CMD"));
+ aList.append(action("EDGE_THICKNESS_CMD"));
aList.append(action("SHOW_ISOLINES_CMD"));
aList.append(action("ISOLINES_CMD"));
aList.append(mySeparator3);
anActions.append(action("COLOR_CMD"));
anActions.append(action("DEFLECTION_CMD"));
anActions.append(action("TRANSPARENCY_CMD"));
+ anActions.append(action("EDGE_THICKNESS_CMD"));
anActions.append(action("SHOW_ISOLINES_CMD"));
anActions.append(action("ISOLINES_CMD"));
anActions.append(action("CLEAN_HISTORY_CMD"));
anActions.append(action("COLOR_CMD"));
anActions.append(action("DEFLECTION_CMD"));
anActions.append(action("TRANSPARENCY_CMD"));
+ anActions.append(action("EDGE_THICKNESS_CMD"));
anActions.append(mySeparator1);
anActions.append(action("SHOW_ONLY_CMD"));
anActions.append(action("HIDE_CMD"));
#pragma warning(disable: 4702)
#endif
+#define EDGE_THICKNESS_DBG
+#ifdef EDGE_THICKNESS_DBG
+ #include <iostream>
+#endif /*EDGE_THICKNESS_DBG*/
+
/// defines the local context mouse selection sensitivity
const int MOUSE_SENSITIVITY_IN_PIXEL = 10;
// bos#40617: Apply clipping planes
// Retrieve the clipping plane from the OCCT Presentation Manager directly,
- // as they are stored in the ViewModel of the OCCViewer in GUI, where we
+ // as they are stored in the ViewModel of the OCCViewer in GUI, where we
// don't have access to.
Handle(ViewerData_AISShape) aShape = Handle(ViewerData_AISShape)::DownCast (anAISIO);
if (!aShape.IsNull() && aShape->IsClippable()) {
// appear "behind" the Groups.
aContext->SetDisplayPriority(anAISIO, FRONT_DISPLAY_PRIORITY);
}
+
#ifdef TINSPECTOR
if (getCallBack()) getCallBack()->Display(anAISIO);
#endif
if (!aAISIO.IsNull()) {
ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
- if (aResult.get()) {
+ if (aResult) {
+ #ifdef EDGE_THICKNESS_DBG
+ std::cout << "XGUI_Displayer::redisplay. theObject is ModelAPI_Result and has AIS_InteractiveObject." << std::endl;
+ #endif /*EDGE_THICKNESS_DBG*/
+
+ { // Set edge thickness
+ // Set edge thickness to subshapes of result
+ std::map<GeomShapePtr, int> aShapes;
+ ModelAPI_Tools::getSubShapesWithEdgeThickness(aResult, aShapes);
+
+ #ifdef EDGE_THICKNESS_DBG
+ for (const auto& shapeAndThickness : aShapes) {
+ std::cout << "Edge thickness of subshape at \"" << shapeAndThickness.first.get() << "\" is " << shapeAndThickness.second << std::endl;
+ }
+ #endif /*EDGE_THICKNESS_DBG*/
+
+ // Displayer overlays presentations of edge shapes with edges of face presentations.
+ // Edges of face presentations are overlaid by edges of solid presentations.
+ // Etc...
+ //
+ // This snippet is circumvention of the behaviour.
+ // Thickness is only assigned to presentations of edge subshapes of a shape.
+ // If a subshape has non-default thickness value, the value overrides thickness value of the parental shape.
+ std::map<GeomShapePtr, int> edges;
+ std::map<GeomShapePtr, int> wires;
+ std::map<GeomShapePtr, int> faces;
+ std::map<GeomShapePtr, int> shells;
+ std::map<GeomShapePtr, int> solids;
+ std::map<GeomShapePtr, int> compsolids;
+ std::map<GeomShapePtr, int> compounds;
+
+ for (auto itShapes = aShapes.begin(); itShapes != aShapes.end();) {
+ const auto& shape = itShapes->first;
+ const auto& thickness = itShapes->second;
+ const auto shapeType = shape->shapeType();
+
+ if (shapeType > GeomAPI_Shape::ShapeType::EDGE) {
+ // Do nothing.
+ }
+ else if (shapeType == GeomAPI_Shape::ShapeType::EDGE)
+ edges.emplace(shape, thickness);
+ else if (shapeType == GeomAPI_Shape::ShapeType::WIRE)
+ wires.emplace(shape, thickness);
+ else if (shapeType == GeomAPI_Shape::ShapeType::FACE)
+ faces.emplace(shape, thickness);
+ else if (shapeType == GeomAPI_Shape::ShapeType::SHELL)
+ shells.emplace(shape, thickness);
+ else if (shapeType == GeomAPI_Shape::ShapeType::SOLID)
+ solids.emplace(shape, thickness);
+ else if (shapeType == GeomAPI_Shape::ShapeType::COMPSOLID)
+ compsolids.emplace(shape, thickness);
+ else if (shapeType == GeomAPI_Shape::ShapeType::COMPOUND)
+ compounds.emplace(shape, thickness);
+
+ itShapes = aShapes.erase(itShapes);
+ }
+
+ std::map<GeomShapePtr, int> mapResultShapeThickness;
+ {
+ const int resultThickness = ModelAPI_Tools::getEdgeThickness(aResult);
+ if (resultThickness > 0) {
+ mapResultShapeThickness.emplace(aResult->shape(), resultThickness);
+ #ifdef EDGE_THICKNESS_DBG
+ std::cout << "Result edge thickness: " << resultThickness << std::endl;
+ #endif /*EDGE_THICKNESS_DBG*/
+ }
+ }
+
+ #ifdef EDGE_THICKNESS_DBG
+ std::cout << std::endl;
+ #endif /*EDGE_THICKNESS_DBG*/
+
+ const std::list<std::map<GeomShapePtr, int>*> thicknessMaps = {&wires, &faces, &shells, &solids, &compsolids, &compounds, &mapResultShapeThickness};
+ for (const auto pThicknessMap : thicknessMaps) {
+ const std::map<GeomShapePtr, int>& thicknessMap = *pThicknessMap;
+ for (const auto& shapeAndThickness : thicknessMap) {
+ const GeomShapePtr& shape = shapeAndThickness.first;
+ const int thickness = shapeAndThickness.second;
+
+ const std::list<GeomShapePtr> shapeEdges = shape->subShapes(GeomAPI_Shape::ShapeType::EDGE, true /*theOnlyUnique*/);
+ for (const auto& shapeEdge : shapeEdges) {
+ if (edges.find(shapeEdge) == edges.end())
+ edges.emplace(shapeEdge, thickness);
+ }
+ }
+ }
+
+ Handle(AIS_ColoredShape) aResShape = Handle(AIS_ColoredShape)::DownCast(aAISIO);
+ Handle(ModuleBase_ResultPrs) aResPrsShape = Handle(ModuleBase_ResultPrs)::DownCast(aResShape);
+ if (!aResPrsShape.IsNull()) {
+ for (const auto& edgeAndTickness : edges) {
+ const GeomShapePtr& edge = edgeAndTickness.first;
+ const int thickness = edgeAndTickness.second;
+
+ if (aAISObj->getShape()->isSubShape(edge)) {
+ aResPrsShape->SetCustomWidth(edge->impl<TopoDS_Shape>(), thickness);
+ aResPrsShape->SetCustomColor(edge->impl<TopoDS_Shape>(), Quantity_Color(Quantity_NameOfColor::Quantity_NOC_BLACK));
+ }
+ else {
+ #ifdef EDGE_THICKNESS_DBG
+ std::cout << "Edge at \"" << edge.get() << "\" is not a subshape of result !" << std::endl;
+ #endif /*EDGE_THICKNESS_DBG*/
+ }
+ }
+ }
+ }
+
// Set color
std::vector<int> aColor;
ModelAPI_Tools::getColor(aResult, aColor);
}
else
{
- aResShape->ClearCustomAspects();
+ // Edge thickness is also custom aspect. Don't remove aspects just because colors aren't assigned.
+ // aResShape->ClearCustomAspects();
}
// Set deflection
double aDeflection = ModelAPI_Tools::getDeflection(aResult);
--- /dev/null
+// 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 "XGUI_EdgeThicknessWidget.h"
+
+
+#include <QHBoxLayout>
+#include <SalomeApp_IntSpinBox.h>
+
+
+XGUI_EdgeThicknessWidget::XGUI_EdgeThicknessWidget(QWidget* theParent)
+ : QWidget(theParent)
+{
+ auto aLayout = new QHBoxLayout(this);
+ aLayout->setContentsMargins(0, 0, 0, 0);
+
+ mySpinBox = new SalomeApp_IntSpinBox();
+ mySpinBox->setRange(1, 5);
+ mySpinBox->setDefaultValue(1);
+ mySpinBox->setSingleStep(1);
+ mySpinBox->setObjectName("EdgeThicknessSpinBox");
+ mySpinBox->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
+ mySpinBox->setValue(1);
+ aLayout->addWidget(mySpinBox, 0, Qt::AlignCenter);
+
+ connect(mySpinBox, SIGNAL(valueChanged(int)), this, SIGNAL(thicknessValueChanged(int)));
+}
+
+void XGUI_EdgeThicknessWidget::setValue(int theValue)
+{
+ bool isSpinBoxBlocked = mySpinBox->blockSignals(true);
+ mySpinBox->setValue(theValue);
+ mySpinBox->blockSignals(isSpinBoxBlocked);
+}
+
+int XGUI_EdgeThicknessWidget::getValue() const
+{
+ return mySpinBox->value();
+}
\ No newline at end of file
--- /dev/null
+// 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
+//
+
+#ifndef XGUI_EdgeThicknessWidget_H
+#define XGUI_EdgeThicknessWidget_H
+
+#include "XGUI.h"
+#include <QWidget>
+
+class SalomeApp_IntSpinBox;
+
+/**
+* \ingroup GUI
+* A class of a widget to chose edge thickness. Range of values is Natural:[0; 5].
+*/
+class XGUI_EdgeThicknessWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+/// Constructor
+ /// \param theParent a parent widget for the dialog
+ /// \param theLabelText if not empty, the information label will be shown in the widget
+ XGUI_EXPORT XGUI_EdgeThicknessWidget(QWidget* theParent);
+ XGUI_EXPORT ~XGUI_EdgeThicknessWidget() = default;
+
+ /// Initializes the dialog with the given value.
+ /// \param theValue edge thickness value
+ void setValue(int theValue);
+
+ /// Returns the current edge thickness value.
+ /// \return value
+ int getValue() const;
+
+signals:
+ void thicknessValueChanged(int);
+
+private:
+ SalomeApp_IntSpinBox* mySpinBox;
+};
+
+#endif // XGUI_EdgeThicknessWidget_H
\ No newline at end of file
#include "XGUI_MenuMgr.h"
#include "XGUI_ColorDialog.h"
#include "XGUI_DeflectionDialog.h"
+#include "XGUI_EdgeThicknessWidget.h"
#include "XGUI_TransparencyWidget.h"
#include "XGUI_ContextMenuMgr.h"
#include "XGUI_Displayer.h"
moveObjects(theId == "MOVE_SPLIT_CMD");
else if (theId == "RECOVER_CMD")
recoverFeature();
+ else if (theId == "EDGE_THICKNESS_CMD")
+ changeEdgeThickness(aSelectedObjects);
else if (theId == "COLOR_CMD")
changeColor(aSelectedObjects);
else if (theId == "AUTOCOLOR_CMD")
bool XGUI_Workshop::canChangeProperty(const QString& theActionName) const
{
if (theActionName == "COLOR_CMD" ||
+ theActionName == "EDGE_THICKNESS_CMD" ||
theActionName == "DEFLECTION_CMD" ||
theActionName == "TRANSPARENCY_CMD") {
QObjectPtrList anObjects = mySelector->selection()->selectedObjects();
+ // List of std::shared_ptr<ModelAPI_Object>
std::set<std::string> aTypes;
aTypes.insert(ModelAPI_ResultGroup::group());
aTypes.insert(ModelAPI_ResultBody::group());
aTypes.insert(ModelAPI_ResultPart::group());
+ /* TODO Get shape type correctly.
+ if (theActionName == "COLOR_CMD") {
+ // Do not show Color dialog in context menus if nothing face-containing is selected.
+ bool isFaceContainingShapeSelected = false;
+ for (const auto& object : anObjects) {
+ if (object->shape().ShapeType() <= TopAbs_ShapeEnum::TopAbs_FACE) {
+ isFaceContainingShapeSelected = true;
+ break;
+ }
+ }
+
+ if (!isFaceContainingShapeSelected)
+ return false;
+ }
+ else if (theActionName == "EDGE_THICKNESS_CMD") {
+ // Do not show Edge Thickness dialog in context menus if nothing edge-containing is selected.
+ bool isEdgeContainingShapeSelected = false;
+ for (const auto& object : anObjects) {
+ if (object->shape().ShapeType() <= TopAbs_ShapeEnum::TopAbs_EDGE) {
+ isEdgeContainingShapeSelected = true;
+ break;
+ }
+ }
+
+ if (!isEdgeContainingShapeSelected)
+ return false;
+ }*/
+
return hasResults(anObjects, aTypes);
}
if (theActionName == "AUTOCOLOR_CMD") {
}
}
+
+//**************************************************************
+/// Returns user-defined default edge thickness.
+int getDefaultEdgeThickness()
+{
+ return Config_PropManager::integer("Visualization", "shaper_default_edge_thickness");
+}
+
+
+
+//**************************************************************
+void XGUI_Workshop::changeEdgeThickness(const QMap<ResultPtr, QList<GeomShapePtr>>& theSelectedObjects)
+{
+ int thickness = -1;
+ // 1. find current edge thickness of the object. This is an edge thickness of AIS presentation.
+ // The objects are iterated until a first valid thickness is found.
+ QList<ModuleBase_ViewerPrsPtr> aValues = mySelector->selection()->getSelected(ModuleBase_ISelection::Viewer);
+ const bool aEdgeThicknessOfSubShapesEnabled = Config_PropManager::boolean("Visualization", "result_subshape_with_edge_thickness");
+ foreach(ResultPtr aResult, theSelectedObjects.keys())
+ {
+ if (!aResult)
+ continue;
+
+ foreach(GeomShapePtr aShape, theSelectedObjects[aResult]) {
+ if (aResult->shape()->impl<TopoDS_Shape>().IsEqual(aShape->impl<TopoDS_Shape>()) || !aEdgeThicknessOfSubShapesEnabled)
+ thickness = ModelAPI_Tools::getEdgeThickness(aResult);
+ else if (!aShape->isNull()) {
+ thickness = ModelAPI_Tools::getSubShapeEdgeThickness(aResult, aShape);
+ if (thickness <= 0)
+ thickness = ModelAPI_Tools::getEdgeThickness(aResult);
+ }
+
+ if (thickness <= 0) {
+ AISObjectPtr anAISObj = myDisplayer->getAISObject(aResult);
+ if (anAISObj) {
+ thickness = getDefaultEdgeThickness();
+ const double aAISThickness = anAISObj->width();
+ if (aAISThickness >= 1)
+ thickness = int(aAISThickness);
+ }
+ }
+
+ if (thickness <= 0)
+ thickness = getDefaultEdgeThickness();
+
+ if (thickness > 0 || !aEdgeThicknessOfSubShapesEnabled)
+ break;
+ }
+
+ if (thickness > 0)
+ break;
+ }
+
+ if (thickness <= 0)
+ return;
+
+ if (!abortAllOperations())
+ return;
+
+ // 2. show the dialog to change the value
+ const auto dialog = new XGUI_PropertyDialog(desktop());
+ dialog->setWindowTitle(tr("Edge Thickness"));
+ const XGUI_EdgeThicknessWidget* edgeThicknessWidget = new XGUI_EdgeThicknessWidget(dialog);
+ dialog->setContent(edgeThicknessWidget);
+ edgeThicknessWidget->setValue(thickness);
+ if (dialog->exec() != QDialog::Accepted)
+ return;
+
+ // bool isSetToShape = dialog->isSetOnSubShape();
+ const bool isSetToShape = true;
+
+ // 3. abort the previous operation and start a new one
+ SessionPtr aMgr = ModelAPI_Session::get();
+ QString aDescription = contextMenuMgr()->action("EDGE_THICKNESS_CMD")->text();
+
+ aMgr->startOperation(aDescription.toStdString());
+
+ // 4. set the value to all results and subshapes from result (if subshape of result were selected).
+ const int newThickness = edgeThicknessWidget->getValue();
+ foreach(ResultPtr aResult, theSelectedObjects.keys()) {
+ if (!aResult)
+ continue;
+
+ ResultBodyPtr aBodyResult = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aResult);
+ foreach(GeomShapePtr aShape, theSelectedObjects[aResult]) {
+ if (aResult->shape()->impl<TopoDS_Shape>().IsEqual(aShape->impl<TopoDS_Shape>()) || !aEdgeThicknessOfSubShapesEnabled || !isSetToShape) {
+ if (aResult.get() != NULL) {
+ // change edge thickness for all sub-solids
+ std::list<ResultPtr> allRes;
+ ModelAPI_Tools::allSubs(aBodyResult, allRes);
+ for (std::list<ResultPtr>::iterator aRes = allRes.begin(); aRes != allRes.end(); aRes++) {
+ ModelAPI_Tools::setEdgeThickness(*aRes, newThickness);
+ }
+ ModelAPI_Tools::setEdgeThickness(aResult, newThickness);
+ }
+ if (!aEdgeThicknessOfSubShapesEnabled)
+ break;
+ }
+ else if (!aShape->isNull()) {
+ ModelAPI_Tools::setSubShapeEdgeThickness(aResult, aShape, newThickness);
+ }
+ }
+ }
+
+ Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
+ aMgr->finishOperation();
+ updateCommandStatus();
+ myViewerProxy->update();
+}
+
+
//**************************************************************
void XGUI_Workshop::changeColor(const QMap<ResultPtr, QList<GeomShapePtr>>& theSelectedObjects)
{
/// \return boolean value
bool canChangeProperty(const QString& theActionName) const;
+ /// Change edge thickness of the results if it is possible.
+ /// The operation is available for construction, body and group results.
+ /// \param theObjects refers to selected objects.
+ void changeEdgeThickness(const QMap<ResultPtr, QList<GeomShapePtr>>& theObjects);
+
/// Change color of the selected objects (result and subshape of result) if it is possible
/// The operation is available for subshape of result, construction, body and group results
/// theSelectedObjects a list of selected objects
<source>Transparency...</source>
<translation>Transparence...</translation>
</message>
+ <message>
+ <source>Edge Thickness...</source>
+ <translation>Epaisseur Des Aretes...</translation>
+ </message>
<message>
<source>Show</source>
<translation>Voir</translation>