PartDesign: Add support for preview for transforms

This commit is contained in:
Kacper Donat
2025-06-20 20:51:59 +02:00
parent 7f87d87f61
commit 6caceacb95
10 changed files with 229 additions and 282 deletions

View File

@@ -137,13 +137,46 @@ void ViewProviderPreviewExtension::extensionAttach(App::DocumentObject* document
{
ViewProviderExtension::extensionAttach(documentObject);
pcPreviewRoot = new SoSeparator;
pcPreviewShape = new SoPreviewShape;
pcPreviewRoot = new SoSeparator;
pcPreviewRoot->addChild(pcPreviewShape);
updatePreviewShape();
attachPreview();
updatePreview();
}
void ViewProviderPreviewExtension::extensionBeforeDelete()
{
ViewProviderExtension::extensionBeforeDelete();
showPreview(false);
}
void ViewProviderPreviewExtension::showPreview(bool enable)
{
auto feature = getExtendedViewProvider()->getObject<Part::Feature>();
if (!feature) {
return;
}
auto previewExtension = feature->getExtensionByType<Part::PreviewExtension>(true);
if (!previewExtension) {
return;
}
_isPreviewEnabled = enable;
auto annotationRoot = getExtendedViewProvider()->getAnnotation();
if (enable) {
previewExtension->updatePreview();
if (annotationRoot->findChild(pcPreviewRoot) < 0) {
annotationRoot->addChild(pcPreviewRoot);
}
} else {
annotationRoot->removeChild(pcPreviewRoot);
}
}
void ViewProviderPreviewExtension::extensionOnChanged(const App::Property* prop)
{
if (prop == &PreviewColor) {
@@ -153,39 +186,68 @@ void ViewProviderPreviewExtension::extensionOnChanged(const App::Property* prop)
ViewProviderExtension::extensionOnChanged(prop);
}
void ViewProviderPreviewExtension::updatePreviewShape()
void ViewProviderPreviewExtension::attachPreview()
{
pcPreviewRoot->addChild(pcPreviewShape);
}
void ViewProviderPreviewExtension::updatePreview()
{
updatePreviewShape(getPreviewShape(), pcPreviewShape);
}
void ViewProviderPreviewExtension::updatePreviewShape(Part::TopoShape shape,
SoPreviewShape* preview)
{
if (shape.isNull() || preview == nullptr) {
return;
}
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);
const auto updatePreviewShape = [vp](SoPreviewShape* preview, Part::TopoShape shape) {
ViewProviderPartExt::setupCoinGeometry(shape.getShape(),
preview->coords,
preview->faceset,
preview->norm,
preview->lineset,
preview->nodeset,
vp->Deviation.getValue(),
vp->AngularDeflection.getValue(),
false);
};
try {
updatePreviewShape(preview, shape);
} catch (Standard_Failure& e) {
Base::Console().userTranslatedNotification(
tr("Failure while rendering preview: %1. That usually indicates an error with model.")
.arg(QString::fromUtf8(e.GetMessageString()))
.toUtf8());
updatePreviewShape(preview, {});
}
// 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();
// each distinct edge. Until that is fixed, this code forces each edge to use the first
// material.
unsigned lineCoordsCount = preview->lineset->coordIndex.getNum();
unsigned lineCount = 1;
for (unsigned i = 0; i < lineCoordsCount; ++i) {
if (pcPreviewShape->lineset->coordIndex[i] < 0) {
if (preview->lineset->coordIndex[i] < 0) {
lineCount++;
}
}
pcPreviewShape->lineset->materialIndex.setNum(lineCount);
preview->lineset->materialIndex.setNum(lineCount);
for (unsigned i = 0; i < lineCount; ++i) {
pcPreviewShape->lineset->materialIndex.set1Value(i, 0);
preview->lineset->materialIndex.set1Value(i, 0);
}
}