/**************************************************************************** * Copyright (c) 2019 Zheng Lei (realthunder) * * * * This file is part of the FreeCAD CAx development system. * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 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 Library General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this library; see the file COPYING.LIB. If not, * * write to the Free Software Foundation, Inc., 59 Temple Place, * * Suite 330, Boston, MA 02111-1307, USA * * * ****************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include "Inventor/SoAutoZoomTranslation.h" #include "SoFCSelection.h" #include "SoFCUnifiedSelection.h" #include "AxisOrigin.h" using namespace Gui; TYPESYSTEM_SOURCE(Gui::AxisOrigin, Base::BaseClass) AxisOrigin::AxisOrigin() = default; SoGroup* AxisOrigin::getNode() { if (node) { return node; } node.reset(new SoGroup); auto pMat = new SoMaterial(); const SbVec3f verts[13] = { SbVec3f(0, 0, 0), SbVec3f(size, 0, 0), SbVec3f(0, size, 0), SbVec3f(0, 0, size), SbVec3f(dist, dist, 0), SbVec3f(dist, pSize, 0), SbVec3f(pSize, dist, 0), // XY Plane SbVec3f(dist, 0, dist), SbVec3f(dist, 0, pSize), SbVec3f(pSize, 0, dist), // XY Plane SbVec3f(0, dist, dist), SbVec3f(0, pSize, dist), SbVec3f(0, dist, pSize) // XY Plane }; // indexes used to create the edges const int32_t lines[21] = {0, 1, -1, 0, 2, -1, 0, 3, -1, 5, 4, 6, -1, 8, 7, 9, -1, 11, 10, 12, -1}; pMat->diffuseColor.setNum(3); pMat->diffuseColor.set1Value(0, SbColor(1.0f, 0.2f, 0.2f)); pMat->diffuseColor.set1Value(1, SbColor(0.2f, 0.6f, 0.2f)); pMat->diffuseColor.set1Value(2, SbColor(0.2f, 0.2f, 1.0f)); pMat->diffuseColor.set1Value(4, SbColor(0.8f, 0.8f, 0.8f)); auto pCoords = new SoCoordinate3(); pCoords->point.setNum(3); pCoords->point.setValues(0, 13, verts); auto zoom = new SoAutoZoomTranslation; zoom->scaleFactor = scale; auto style = new SoDrawStyle(); style->lineWidth = lineSize; style->pointSize = pointSize; auto matBinding = new SoMaterialBinding; matBinding->value = SoMaterialBinding::PER_FACE_INDEXED; node->addChild(zoom); node->addChild(style); node->addChild(matBinding); node->addChild(pMat); node->addChild(pCoords); #define CREATE_AXIS(_type, _key, _count, _offset, _mat) \ do { \ const char* label = _key; \ if (labels.size()) { \ auto iter = labels.find(_key); \ if (iter == labels.end()) \ break; \ else if (iter->second.size()) \ label = iter->second.c_str(); \ } \ auto pAxis = new SoFCSelection; \ pAxis->applySettings(); \ pAxis->style = SoFCSelection::EMISSIVE_DIFFUSE; \ pAxis->subElementName = label; \ nodeMap[label].reset(pAxis); \ node->addChild(pAxis); \ auto _type = new SoIndexed##_type##Set; \ pAxis->addChild(_type); \ _type->coordIndex.setNum(_count); \ _type->coordIndex.setValues(0, _count, lines + _offset); \ _type->materialIndex.setValue(_mat); \ } while (0) CREATE_AXIS(Point, "O", 1, 0, 4); CREATE_AXIS(Line, "X", 3, 0, 0); CREATE_AXIS(Line, "Y", 3, 3, 1); CREATE_AXIS(Line, "Z", 3, 6, 2); CREATE_AXIS(Line, "XY", 4, 9, 2); CREATE_AXIS(Line, "XZ", 4, 13, 1); CREATE_AXIS(Line, "YZ", 4, 17, 0); return node; } bool AxisOrigin::getElementPicked(const SoPickedPoint* pp, std::string& subname) const { SoPath* path = pp->getPath(); int length = path->getLength(); for (int i = 0; i < length; ++i) { auto node = path->getNodeFromTail(i); if (node->isOfType(SoFCSelection::getClassTypeId())) { subname = static_cast(node)->subElementName.getValue().getString(); return true; } else if (node->isOfType(SoFCSelectionRoot::getClassTypeId())) { break; } } return false; } bool AxisOrigin::getDetailPath(const char* subname, SoFullPath* pPath, SoDetail*&) const { if (!node) { return false; } if (!subname || !subname[0]) { return true; } auto it = nodeMap.find(subname); if (it == nodeMap.end()) { return false; } pPath->append(node); pPath->append(it->second); return true; } void AxisOrigin::setLineWidth(float size) { if (size != lineSize) { node.reset(); nodeMap.clear(); lineSize = size; } } void AxisOrigin::setPointSize(float size) { if (pointSize != size) { pointSize = size; node.reset(); nodeMap.clear(); } } void AxisOrigin::setAxisLength(float size) { if (this->size != size) { this->size = size; node.reset(); nodeMap.clear(); } } void AxisOrigin::setPlane(float size, float dist) { if (pSize != size || this->dist != dist) { pSize = size; this->dist = dist; node.reset(); nodeMap.clear(); } } void AxisOrigin::setScale(float scale) { if (this->scale != scale) { this->scale = scale; node.reset(); nodeMap.clear(); } } void AxisOrigin::setLabels(const std::map& labels) { this->labels = labels; node.reset(); nodeMap.clear(); }