/*************************************************************************** * Copyright (c) 2021 Abdullah Tahiri * * * * 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 "PreCompiled.h" #ifndef _PreComp_ # include # include # include # include # include # include # include # include #endif // #ifndef _PreComp_ #include #include #include #include #include #include #include #include "EditModeGeometryCoinManager.h" #include "EditModeGeometryCoinConverter.h" #include "ViewProviderSketchCoinAttorney.h" using namespace SketcherGui; using namespace Sketcher; //**************************** EditModeGeometryCoinManager class ****************************** EditModeGeometryCoinManager::EditModeGeometryCoinManager( ViewProviderSketch &vp, DrawingParameters & drawingParams, GeometryLayerParameters & geometryLayerParams, AnalysisResults & analysisResultStruct, EditModeScenegraphNodes & editModeScenegraph, CoinMapping & coinMap): viewProvider(vp), drawingParameters(drawingParams), geometryLayerParameters(geometryLayerParams), analysisResults(analysisResultStruct), editModeScenegraphNodes(editModeScenegraph), coinMapping(coinMap) {} EditModeGeometryCoinManager::~EditModeGeometryCoinManager() {} void EditModeGeometryCoinManager::processGeometry(const GeoListFacade & geolistfacade) { // enable all layers editModeScenegraphNodes.PointsGroup->enable.setNum(geometryLayerParameters.CoinLayers); editModeScenegraphNodes.CurvesGroup->enable.setNum(geometryLayerParameters.CoinLayers); SbBool *swsp = editModeScenegraphNodes.PointsGroup->enable.startEditing(); SbBool *swsc = editModeScenegraphNodes.CurvesGroup->enable.startEditing(); for(int l=0; lenable.finishEditing(); editModeScenegraphNodes.CurvesGroup->enable.finishEditing(); // Define the coin nodes that will be filled in with the geometry layers GeometryLayerNodes geometrylayernodes { editModeScenegraphNodes.PointsMaterials, editModeScenegraphNodes.PointsCoordinate, editModeScenegraphNodes.CurvesMaterials, editModeScenegraphNodes.CurvesCoordinate, editModeScenegraphNodes.CurveSet }; // process geometry layers EditModeGeometryCoinConverter gcconv(viewProvider, geometrylayernodes, drawingParameters, geometryLayerParameters, coinMapping); gcconv.convert(geolistfacade); // set cross coordinates editModeScenegraphNodes.RootCrossSet->numVertices.set1Value(0,2); editModeScenegraphNodes.RootCrossSet->numVertices.set1Value(1,2); analysisResults.combRepresentationScale = gcconv.getCombRepresentationScale(); analysisResults.boundingBoxMagnitudeOrder = exp(ceil(log(std::abs(gcconv.getBoundingBoxMaxMagnitude())))); analysisResults.bsplineGeoIds = gcconv.getBSplineGeoIds(); } void EditModeGeometryCoinManager::updateGeometryColor(const GeoListFacade & geolistfacade, bool issketchinvalid) { // Lambdas for convenience retrieval of geometry information auto isConstructionGeom = [&geolistfacade](int GeoId) { auto geom = geolistfacade.getGeometryFacadeFromGeoId(GeoId); if (geom) return geom->getConstruction(); return false; }; auto isDefinedGeomPoint = [&geolistfacade](int GeoId) { auto geom = geolistfacade.getGeometryFacadeFromGeoId(GeoId); if (geom) return geom->isGeoType(Part::GeomPoint::getClassTypeId()) && !geom->getConstruction(); return false; }; auto isInternalAlignedGeom = [&geolistfacade](int GeoId) { auto geom = geolistfacade.getGeometryFacadeFromGeoId(GeoId); if (geom) { return geom->isInternalAligned(); } return false; }; auto isFullyConstraintElement = [&geolistfacade](int GeoId) { auto geom = geolistfacade.getGeometryFacadeFromGeoId(GeoId); if(geom) { if(geom->hasExtension(Sketcher::SolverGeometryExtension::getClassTypeId())) { auto solvext = std::static_pointer_cast( geom->getExtension(Sketcher::SolverGeometryExtension::getClassTypeId()).lock()); return (solvext->getGeometry() == Sketcher::SolverGeometryExtension::FullyConstraint); } } return false; }; // Update Colors SbColor *crosscolor = editModeScenegraphNodes.RootCrossMaterials->diffuseColor.startEditing(); auto viewOrientationFactor = ViewProviderSketchCoinAttorney::getViewOrientationFactor(viewProvider); for(int l=0; ldiffuseColor.getNum(); SbColor *pcolor = editModeScenegraphNodes.PointsMaterials[l]->diffuseColor.startEditing(); int CurvNum = editModeScenegraphNodes.CurvesMaterials[l]->diffuseColor.getNum(); SbColor *color = editModeScenegraphNodes.CurvesMaterials[l]->diffuseColor.startEditing(); SbVec3f *verts = editModeScenegraphNodes.CurvesCoordinate[l]->point.startEditing(); SbVec3f *pverts = editModeScenegraphNodes.PointsCoordinate[l]->point.startEditing(); float x,y,z; // colors of the point set if( issketchinvalid ) { for (int i=0; i < PtNum; i++) pcolor[i] = drawingParameters.InvalidSketchColor; } else { for (int i=0; i < PtNum; i++) { if ( !(i == 0 && l == 0) && ViewProviderSketchCoinAttorney::isSketchFullyConstrained(viewProvider)) {// root point is not coloured pcolor[i] = drawingParameters.FullyConstrainedColor; } else { int GeoId = coinMapping.getPointGeoId(i, l); bool constrainedElement = isFullyConstraintElement(GeoId); if(isInternalAlignedGeom(GeoId)) { if(constrainedElement) pcolor[i] = drawingParameters.FullyConstraintInternalAlignmentColor; else pcolor[i] = drawingParameters.InternalAlignedGeoColor; } else { if(!isDefinedGeomPoint(GeoId)) { if(constrainedElement) pcolor[i] = drawingParameters.FullyConstraintConstructionPointColor; else pcolor[i] = drawingParameters.VertexColor; } else { // this is a defined GeomPoint if(constrainedElement) pcolor[i] = drawingParameters.FullyConstraintElementColor; else pcolor[i] = drawingParameters.CurveColor; } } } } } // update rendering height of points auto getRenderHeight = [this](DrawingParameters::GeometryRendering renderingtype, float toprendering, float midrendering, float lowrendering) { if(drawingParameters.topRenderingGeometry == renderingtype) return toprendering; else if(drawingParameters.midRenderingGeometry == renderingtype) return midrendering; else return lowrendering; }; float zNormPoint = getRenderHeight(DrawingParameters::GeometryRendering::NormalGeometry, drawingParameters.zHighPoints, drawingParameters.zLowPoints, drawingParameters.zLowPoints); float zConstrPoint = getRenderHeight(DrawingParameters::GeometryRendering::Construction, drawingParameters.zHighPoints, drawingParameters.zLowPoints, drawingParameters.zLowPoints); for (int i=0; i < PtNum; i++) { // 0 is the origin if( i == 0 && l == 0 ) { // reset root point to lowest pverts[i].setValue(0, 0, viewOrientationFactor * drawingParameters.zRootPoint); } else { pverts[i].getValue(x,y,z); auto geom = geolistfacade.getGeometryFacadeFromGeoId(coinMapping.getPointGeoId(i, l)); if(geom) { if(geom->getConstruction()) pverts[i].setValue(x,y,viewOrientationFactor * zConstrPoint); else pverts[i].setValue(x,y,viewOrientationFactor * zNormPoint); } } } auto preselectpoint = ViewProviderSketchCoinAttorney::getPreselectPoint(viewProvider); auto preselectcross = ViewProviderSketchCoinAttorney::getPreselectCross(viewProvider); auto preselectcurve = ViewProviderSketchCoinAttorney::getPreselectCurve(viewProvider); MultiFieldId preselectpointmfid; if ( preselectcross == 0) { if(l == 0) // cross only in layer 0 pcolor[0] = drawingParameters.PreselectColor; } else if (preselectpoint != -1) { preselectpointmfid = coinMapping.getIndexLayer(preselectpoint); if (MultiFieldId::Invalid != preselectpointmfid && preselectpointmfid.layerId == l && preselectpointmfid.fieldIndex < PtNum) pcolor[preselectpointmfid.fieldIndex] = drawingParameters.PreselectColor; } ViewProviderSketchCoinAttorney::executeOnSelectionPointSet(viewProvider, [pcolor, PtNum, preselectpointmfid, layerId = l, &coinMapping = coinMapping, drawingParameters = this->drawingParameters](const int i) { auto pointindex = coinMapping.getIndexLayer(i); if (layerId == pointindex.layerId && pointindex.fieldIndex >= 0 && pointindex.fieldIndex < PtNum) { pcolor[pointindex.fieldIndex] = (preselectpointmfid == pointindex) ? drawingParameters.PreselectSelectedColor : drawingParameters.SelectColor; } }); // update colors and rendering height of the curves float zNormLine = getRenderHeight(DrawingParameters::GeometryRendering::NormalGeometry, drawingParameters.zHighLines, drawingParameters.zMidLines, drawingParameters.zLowLines); float zConstrLine = getRenderHeight(DrawingParameters::GeometryRendering::Construction, drawingParameters.zHighLines, drawingParameters.zMidLines, drawingParameters.zLowLines); float zExtLine = getRenderHeight(DrawingParameters::GeometryRendering::ExternalGeometry, drawingParameters.zHighLines, drawingParameters.zMidLines, drawingParameters.zLowLines); int j=0; // vertexindex for (int i=0; i < CurvNum; i++) { int GeoId = coinMapping.getCurveGeoId(i, l); // CurvId has several vertices associated to 1 material //edit->CurveSet->numVertices => [i] indicates number of vertex for line i. int indexes = (editModeScenegraphNodes.CurveSet[l]->numVertices[i]); bool selected = ViewProviderSketchCoinAttorney::isCurveSelected(viewProvider, GeoId); bool preselected = (preselectcurve == GeoId); bool constrainedElement = isFullyConstraintElement(GeoId); if (selected && preselected) { color[i] = drawingParameters.PreselectSelectedColor; for (int k=j; jdiffuseColor.finishEditing(); editModeScenegraphNodes.PointsMaterials[l]->diffuseColor.finishEditing(); editModeScenegraphNodes.CurvesCoordinate[l]->point.finishEditing(); editModeScenegraphNodes.CurveSet[l]->numVertices.finishEditing(); } editModeScenegraphNodes.RootCrossMaterials->diffuseColor.finishEditing(); } void EditModeGeometryCoinManager::createEditModeInventorNodes() { // stuff for the points ++++++++++++++++++++++++++++++++++++++ editModeScenegraphNodes.PointsGroup = new SmSwitchboard; editModeScenegraphNodes.EditRoot->addChild(editModeScenegraphNodes.PointsGroup); auto concat = [](std::string string, int i) { return string+std::to_string(i); }; for(int i=0; i < geometryLayerParameters.CoinLayers; i++) { SoSeparator * sep = new SoSeparator; sep->ref(); auto somaterial = new SoMaterial; editModeScenegraphNodes.PointsMaterials.push_back(somaterial); editModeScenegraphNodes.PointsMaterials[i]->setName(concat("PointsMaterials_",i).c_str()); sep->addChild(editModeScenegraphNodes.PointsMaterials[i]); SoMaterialBinding *MtlBind = new SoMaterialBinding; MtlBind->setName(concat("PointsMaterialBinding",i).c_str()); MtlBind->value = SoMaterialBinding::PER_VERTEX; sep->addChild(MtlBind); auto coords = new SoCoordinate3; editModeScenegraphNodes.PointsCoordinate.push_back(coords); editModeScenegraphNodes.PointsCoordinate[i]->setName(concat("PointsCoordinate",i).c_str()); sep->addChild(editModeScenegraphNodes.PointsCoordinate[i]); auto drawstyle = new SoDrawStyle; editModeScenegraphNodes.PointsDrawStyle.push_back(drawstyle); editModeScenegraphNodes.PointsDrawStyle[i]->setName(concat("PointsDrawStyle",i).c_str()); editModeScenegraphNodes.PointsDrawStyle[i]->pointSize = 8 * drawingParameters.pixelScalingFactor; sep->addChild(editModeScenegraphNodes.PointsDrawStyle[i]); auto pointset = new SoMarkerSet; editModeScenegraphNodes.PointSet.push_back(pointset); editModeScenegraphNodes.PointSet[i]->setName(concat("PointSet",i).c_str()); editModeScenegraphNodes.PointSet[i]->markerIndex = Gui::Inventor::MarkerBitmaps::getMarkerIndex("CIRCLE_FILLED", drawingParameters.markerSize); sep->addChild(editModeScenegraphNodes.PointSet[i]); editModeScenegraphNodes.PointsGroup->addChild(sep); sep->unref(); } // stuff for the Curves +++++++++++++++++++++++++++++++++++++++ editModeScenegraphNodes.CurvesGroup = new SmSwitchboard; editModeScenegraphNodes.EditRoot->addChild(editModeScenegraphNodes.CurvesGroup); for(int i=0; i < geometryLayerParameters.CoinLayers; i++) { SoSeparator * sep = new SoSeparator; sep->ref(); auto somaterial = new SoMaterial; editModeScenegraphNodes.CurvesMaterials.push_back(somaterial); editModeScenegraphNodes.CurvesMaterials[i]->setName(concat("CurvesMaterials",i).c_str()); sep->addChild(editModeScenegraphNodes.CurvesMaterials[i]); auto MtlBind = new SoMaterialBinding; MtlBind->setName(concat("CurvesMaterialsBinding",i).c_str()); MtlBind->value = SoMaterialBinding::PER_FACE; sep->addChild(MtlBind); auto coords = new SoCoordinate3; editModeScenegraphNodes.CurvesCoordinate.push_back(coords); editModeScenegraphNodes.CurvesCoordinate[i]->setName(concat("CurvesCoordinate",i).c_str()); sep->addChild(editModeScenegraphNodes.CurvesCoordinate[i]); auto drawstyle = new SoDrawStyle; editModeScenegraphNodes.CurvesDrawStyle.push_back(drawstyle); editModeScenegraphNodes.CurvesDrawStyle[i]->setName(concat("CurvesDrawStyle",i).c_str()); editModeScenegraphNodes.CurvesDrawStyle[i]->lineWidth = 3 * drawingParameters.pixelScalingFactor; /* Demo code to introduce a dashed line if(i == 1) { editModeScenegraphNodes.CurvesDrawStyle[i]->linePattern = 0x3CF2; editModeScenegraphNodes.CurvesDrawStyle[i]->linePatternScaleFactor = 5; }*/ sep->addChild(editModeScenegraphNodes.CurvesDrawStyle[i]); auto solineset = new SoLineSet; editModeScenegraphNodes.CurveSet.push_back(solineset); editModeScenegraphNodes.CurveSet[i]->setName(concat("CurvesLineSet",i).c_str()); sep->addChild(editModeScenegraphNodes.CurveSet[i]); editModeScenegraphNodes.CurvesGroup->addChild(sep); sep->unref(); } }