PartDesign: Add transparent previews

This commit is contained in:
Kacper Donat
2024-10-13 13:33:18 +02:00
parent 38db306a84
commit 7f87d87f61
58 changed files with 1438 additions and 1021 deletions

View File

@@ -0,0 +1,197 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/****************************************************************************
* *
* Copyright (c) 2025 Kacper Donat <kacper@kadet.net> *
* *
* This file is part of FreeCAD. *
* *
* FreeCAD 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. *
* *
* FreeCAD 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 FreeCAD. If not, see *
* <https://www.gnu.org/licenses/>. *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <Inventor/nodes/SoDrawStyle.h>
# include <Inventor/nodes/SoLightModel.h>
# include <Inventor/nodes/SoMaterial.h>
# include <Inventor/nodes/SoPickStyle.h>
# include <Inventor/nodes/SoPolygonOffset.h>
#endif
#include "ViewProviderPreviewExtension.h"
#include "ViewProviderExt.h"
#include <Gui/Utilities.h>
#include <Gui/Inventor/So3DAnnotation.h>
#include <Mod/Part/App/Tools.h>
using namespace PartGui;
SO_NODE_SOURCE(SoPreviewShape);
const SbColor SoPreviewShape::defaultColor = SbColor(1.F, 0.F, 1.F);
SoPreviewShape::SoPreviewShape()
: coords(new SoCoordinate3)
, norm(new SoNormal)
, faceset(new PartGui::SoBrepFaceSet)
, lineset(new PartGui::SoBrepEdgeSet)
, nodeset(new PartGui::SoBrepPointSet)
{
SO_NODE_CONSTRUCTOR(SoPreviewShape);
SO_NODE_ADD_FIELD(color, (defaultColor));
SO_NODE_ADD_FIELD(transparency, (defaultTransparency));
SO_NODE_ADD_FIELD(lineWidth, (defaultLineWidth));
auto pickStyle = new SoPickStyle;
pickStyle->style = SoPickStyle::UNPICKABLE;
auto* solidLineStyle = new SoDrawStyle();
solidLineStyle->lineWidth.connectFrom(&lineWidth);
auto* hiddenLineStyle = new SoDrawStyle();
hiddenLineStyle->lineWidth.connectFrom(&lineWidth);
hiddenLineStyle->linePattern = 0xF0F0;
auto* solidColorLightModel = new SoLightModel();
solidColorLightModel->model = SoLightModel::BASE_COLOR;
auto* normalBinding = new SoNormalBinding();
normalBinding->value = SoNormalBinding::PER_VERTEX_INDEXED;
// This should be OVERALL but then line pattern does not work correctly
// Probably a bug in coin to be investigated.
auto* materialBinding = new SoMaterialBinding();
materialBinding->value = SoMaterialBinding::PER_FACE_INDEXED;
auto* material = new SoMaterial;
material->diffuseColor.connectFrom(&color);
material->transparency.connectFrom(&transparency);
auto* polygonOffset = new SoPolygonOffset;
polygonOffset->factor = -0.00001F;
polygonOffset->units = -1.0F;
polygonOffset->on = true;
polygonOffset->styles = SoPolygonOffset::FILLED;
auto* lineMaterial = new SoMaterial;
lineMaterial->diffuseColor.connectFrom(&color);
lineMaterial->transparency = 0.0f;
auto* lineSep = new SoSeparator;
lineSep->addChild(normalBinding);
lineSep->addChild(materialBinding);
lineSep->addChild(solidColorLightModel);
lineSep->addChild(lineMaterial);
lineSep->addChild(lineset);
auto* annotation = new Gui::So3DAnnotation;
annotation->addChild(hiddenLineStyle);
annotation->addChild(material);
annotation->addChild(lineSep);
annotation->addChild(polygonOffset);
annotation->addChild(faceset);
SoSeparator::addChild(pickStyle);
SoSeparator::addChild(solidLineStyle);
SoSeparator::addChild(material);
SoSeparator::addChild(coords);
SoSeparator::addChild(norm);
SoSeparator::addChild(lineSep);
SoSeparator::addChild(polygonOffset);
SoSeparator::addChild(faceset);
SoSeparator::addChild(annotation);
}
EXTENSION_PROPERTY_SOURCE(PartGui::ViewProviderPreviewExtension, Gui::ViewProviderExtension)
ViewProviderPreviewExtension::ViewProviderPreviewExtension()
{
const Base::Color magenta(1.0F, 0.0F, 1.0F);
EXTENSION_ADD_PROPERTY_TYPE(
PreviewColor,
(magenta),
"Preview",
static_cast<App::PropertyType>(App::Prop_Transient | App::Prop_Hidden),
"Color used for 3D Preview");
initExtensionType(ViewProviderPreviewExtension::getExtensionClassTypeId());
}
void ViewProviderPreviewExtension::extensionAttach(App::DocumentObject* documentObject)
{
ViewProviderExtension::extensionAttach(documentObject);
pcPreviewShape = new SoPreviewShape;
pcPreviewRoot = new SoSeparator;
pcPreviewRoot->addChild(pcPreviewShape);
updatePreviewShape();
}
void ViewProviderPreviewExtension::extensionOnChanged(const App::Property* prop)
{
if (prop == &PreviewColor) {
pcPreviewShape->color.setValue(Base::convertTo<SbColor>(PreviewColor.getValue()));
}
ViewProviderExtension::extensionOnChanged(prop);
}
void ViewProviderPreviewExtension::updatePreviewShape()
{
auto vp = freecad_cast<ViewProviderPartExt*>(getExtendedViewProvider());
if (!vp) {
return;
}
ViewProviderPartExt::setupCoinGeometry(getPreviewShape().getShape(),
pcPreviewShape->coords,
pcPreviewShape->faceset,
pcPreviewShape->norm,
pcPreviewShape->lineset,
pcPreviewShape->nodeset,
vp->Deviation.getValue(),
vp->AngularDeflection.getValue(),
false);
// For some reason line patterns are not rendered correctly if material binding is set to
// anything other than PER_FACE. PER_FACE material binding seems to require materialIndex per
// each distinct edge. Until that is fixed, this code forces each edge to use the first material.
unsigned lineCoordsCount = pcPreviewShape->lineset->coordIndex.getNum();
unsigned lineCount = 1;
for (unsigned i = 0; i < lineCoordsCount; ++i) {
if (pcPreviewShape->lineset->coordIndex[i] < 0) {
lineCount++;
}
}
pcPreviewShape->lineset->materialIndex.setNum(lineCount);
for (unsigned i = 0; i < lineCount; ++i) {
pcPreviewShape->lineset->materialIndex.set1Value(i, 0);
}
}
namespace Gui {
EXTENSION_PROPERTY_SOURCE_TEMPLATE(PartGui::ViewProviderPreviewExtensionPython, PartGui::ViewProviderPreviewExtension)
// explicit template instantiation
template class PartGuiExport ViewProviderExtensionPythonT<PartGui::ViewProviderPreviewExtension>;
}