diff --git a/TIGLCreator/src/TIGLCreatorDocument.cpp b/TIGLCreator/src/TIGLCreatorDocument.cpp index 2ca889f45..cd53ef021 100644 --- a/TIGLCreator/src/TIGLCreatorDocument.cpp +++ b/TIGLCreator/src/TIGLCreatorDocument.cpp @@ -65,6 +65,7 @@ #include "CTiglPoint.h" #include "CTiglError.h" #include "TIGLCreatorSettings.h" +#include "CTiglTransformation.h" #include "CTiglIntersectionCalculation.h" #include "TIGLCreatorWindow.h" #include "TIGLCreatorEtaXsiDialog.h" @@ -81,6 +82,8 @@ #include "tiglcommonfunctions.h" #include "CTiglPoint.h" #include "CTiglExportCollada.h" +#include "CNamedShape.h" +#include "TiglSymmetryAxis.h" #include "CCPACSWingCSStructure.h" #include "CCPACSWingSparSegment.h" #include "CCPACSWingRibsDefinition.h" @@ -436,24 +439,40 @@ QString TIGLCreatorDocument::dlgGetWingSelection() } // Wing Component Segment selection Dialog -QString TIGLCreatorDocument::dlgGetWingComponentSegmentSelection() +QString TIGLCreatorDocument::dlgGetWingComponentSegmentSelection(const QString& wingUID) { QStringList compSegs; bool ok; - // Initialize wing list tigl::CCPACSConfiguration& config = GetConfiguration(); - int wingCount = config.GetWingCount(); - for (int i = 1; i <= wingCount; i++) { - tigl::CCPACSWing& wing = config.GetWing(i); - if (wing.IsRotorBlade()) { - continue; + if (wingUID.isEmpty()) { + + int wingCount = config.GetWingCount(); + for (int i = 1; i <= wingCount; i++) { + tigl::CCPACSWing& wing = config.GetWing(i); + if (wing.IsRotorBlade()) { + continue; + } + // Get all component segments + for (int j = 1; j <= wing.GetComponentSegmentCount(); ++j) { + tigl::CCPACSWingComponentSegment& segment = wing.GetComponentSegment(j); + compSegs << segment.GetUID().c_str(); + } } - + } + else { + tigl::CCPACSWing& wing = config.GetWing(wingUID.toStdString()); + if (wing.IsRotorBlade()) { + throw tigl::CTiglError("Selected wing is a rotor blade!", TIGL_ERROR); + } + // Only get component segments of the selected wing for (int j = 1; j <= wing.GetComponentSegmentCount(); ++j) { tigl::CCPACSWingComponentSegment& segment = wing.GetComponentSegment(j); compSegs << segment.GetUID().c_str(); } + if (wing.GetComponentSegmentCount() == 1 && !compSegs.empty()) { + return compSegs[0]; + } } QString choice = QInputDialog::getItem(app, tr("Select Component Segment"), tr("Available Component Segments:"), @@ -775,12 +794,12 @@ void TIGLCreatorDocument::drawComponentByUID(const QString& uid) if (loft) { double opacity = 0; bool shaded = true; - // By default, we display the wing without cutouts (for performance). + // By default, we display the wing without cutouts (for performance). // Therefore, it is visually better to display the flaps using a wireframe rendering by default if (component.GetComponentType() == TIGL_COMPONENT_CONTROL_SURFACE_DEVICE) { shaded = false; } - + auto shape = app->getScene()->displayShape(loft, true, getDefaultShapeColor(), opacity, shaded); app->getScene()->GetShapeManager().addObject(uid.toStdString(), shape); @@ -799,16 +818,16 @@ void TIGLCreatorDocument::drawComponentByUID(const QString& uid) if (objects[0]->Shape() != component.GetLoft()->Shape()) { objects[0]->SetShape(component.GetLoft()->Shape()); } - else { - auto* geometricComp = dynamic_cast(&component); - if (geometricComp) { - if (geometricComp->GetMirroredLoft()) { - if (objects[1]->Shape() != geometricComp->GetMirroredLoft()->Shape()) { - objects[1]->SetShape(geometricComp->GetMirroredLoft()->Shape()); - } + + auto* geometricComp = dynamic_cast(&component); + if (geometricComp) { + if (geometricComp->GetMirroredLoft()) { + if (objects[1]->Shape() != geometricComp->GetMirroredLoft()->Shape()) { + objects[1]->SetShape(geometricComp->GetMirroredLoft()->Shape()); } } } + for (auto& obj : objects) { app->getScene()->getContext()->Display(obj, Standard_False); } @@ -823,10 +842,10 @@ void TIGLCreatorDocument::drawComponentByUID(const QString& uid) void TIGLCreatorDocument::drawControlPointNet() { - auto pre_filter = [](auto* shape) { + auto pre_filter = [](auto* shape) { return shape != nullptr && shape->GetComponentType() != TIGL_COMPONENT_PLANE && - shape->GetComponentType() != TIGL_COMPONENT_CROSS_BEAM_STRUT; + shape->GetComponentType() != TIGL_COMPONENT_CROSS_BEAM_STRUT; }; TIGLGeometryChoserDialog dialog(GetConfiguration().GetUIDManager(), app, pre_filter); @@ -931,7 +950,7 @@ void TIGLCreatorDocument::drawControlPointNetByUID(const QString& uid) void TIGLCreatorDocument::drawConfiguration(bool withDuctCutouts) { tiglConfigurationSetWithDuctCutouts(m_cpacsHandle, (TiglBoolean)withDuctCutouts); - + std::vector shapesToDraw; shapesToDraw.push_back(TIGL_COMPONENT_FUSELAGE); shapesToDraw.push_back(TIGL_COMPONENT_WING); @@ -1115,17 +1134,30 @@ void TIGLCreatorDocument::drawFuselageGuideCurves() app->getScene()->getContext()->UpdateCurrentViewer(); } -void TIGLCreatorDocument::drawWing() +void TIGLCreatorDocument::drawWing(const QString& Uid) { - QString wingUid = dlgGetWingSelection(); - if (wingUid == "") { - return; + QString wingUid; + if (Uid == nullptr) { + wingUid = dlgGetWingSelection(); + if (wingUid == "") { + return; + } + else { + drawComponentByUID(wingUid); + } } else { - drawComponentByUID(wingUid); + wingUid = Uid; } tigl::CCPACSWing& wing = GetConfiguration().GetWing(wingUid.toStdString()); + auto objects = app->getScene()->GetShapeManager().GetIObjectsFromShapeName(wingUid.toStdString()); + for (auto& obj : objects) { + app->getScene()->GetShapeManager().removeObject(obj); + app->getScene()->getContext()->Remove(obj, Standard_False); + } + drawComponentByUID(wingUid); + if (wing.GetComponentSegments()) { for (auto& pcs : wing.GetComponentSegments()->GetComponentSegments()) { @@ -1134,23 +1166,43 @@ void TIGLCreatorDocument::drawWing() } if (auto& teds = pcs->GetControlSurfaces()->GetTrailingEdgeDevices()) { for (auto& ted : teds->GetTrailingEdgeDevices()) { - drawComponentByUID(ted->GetUID().c_str()); + auto objects = app->getScene()->GetShapeManager().GetIObjectsFromShapeName(ted->GetUID()); + for (auto& obj : objects) { + app->getScene()->getContext()->Remove(obj, Standard_False); + } + objects = app->getScene()->GetShapeManager().GetIObjectsFromShapeName(ted->GetUID()+"M"); + for (auto& obj : objects) { + app->getScene()->getContext()->Remove(obj, Standard_False); + } } } if (auto& leds = pcs->GetControlSurfaces()->GetLeadingEdgeDevices()) { for (auto& led : leds->GetLeadingEdgeDevices()) { - drawComponentByUID(led->GetUID().c_str()); + auto objects = app->getScene()->GetShapeManager().GetIObjectsFromShapeName(led->GetUID()); + for (auto& obj : objects) { + app->getScene()->getContext()->Remove(obj, Standard_False); + } + objects = app->getScene()->GetShapeManager().GetIObjectsFromShapeName(led->GetUID()+"M"); + for (auto& obj : objects) { + app->getScene()->getContext()->Remove(obj, Standard_False); + } } } } } } -void TIGLCreatorDocument::drawWingFlaps() +void TIGLCreatorDocument::drawWingFlaps(const QString& Uid) { - QString wingUid = dlgGetWingSelection(); - if (wingUid == "") { - return; + QString wingUid; + if (Uid == nullptr) { + wingUid = dlgGetWingSelection(); + if (wingUid == "") { + return; + } + } + else { + wingUid = Uid; } try { @@ -1191,8 +1243,24 @@ bool TIGLCreatorDocument::drawWingFlaps(tigl::CCPACSWing& wing) return false; } - app->getScene()->deleteAllObjects(); - app->getScene()->displayShape(wing.GetLoftWithCutouts(), true, getDefaultShapeColor()); + auto objects = app->getScene()->GetShapeManager().GetIObjectsFromShapeName(wing.GetUID()); + for (auto& obj : objects) { + app->getScene()->getContext()->Remove(obj, Standard_False); + app->getScene()->GetShapeManager().removeObject(obj); + } + auto shape = app->getScene()->displayShape(wing.GetLoftWithCutouts(), true, getDefaultShapeColor()); + app->getScene()->GetShapeManager().addObject(wing.GetUID(), shape); + + // manually mirror wing with cutouts + tigl::ITiglGeometricComponent& component = GetConfiguration().GetUIDManager().GetGeometricComponent(wing.GetUID()); + auto* geometricComp = dynamic_cast(&component); + + PNamedShape loftNamed(new CNamedShape(wing.GetLoftWithCutouts(), wing.GetUID().c_str())); + PNamedShape mirroredLoft = wing.GetMirroredLoft(loftNamed); + if (mirroredLoft) { + auto shape = app->getScene()->displayShape(mirroredLoft, true, getDefaultShapeSymmetryColor()); + app->getScene()->GetShapeManager().addObject(wing.GetUID(), shape); + } for (auto& pcs : wing.GetComponentSegments()->GetComponentSegments()) { if (!pcs->GetControlSurfaces() || pcs->GetControlSurfaces()->ControlSurfaceCount() == 0) { @@ -1201,18 +1269,33 @@ bool TIGLCreatorDocument::drawWingFlaps(tigl::CCPACSWing& wing) if (auto& teds = pcs->GetControlSurfaces()->GetTrailingEdgeDevices()) { for (auto& ted : teds->GetTrailingEdgeDevices()) { + auto objs = app->getScene()->GetShapeManager().GetIObjectsFromShapeName(ted->GetUID()); + // remove old wireframe flap shapes + for (auto& obj : objs) { + app->getScene()->getContext()->Remove(obj, Standard_True); + app->getScene()->GetShapeManager().removeObject(obj); + } drawWingFlap(ted->GetUID().c_str()); + + } } if (auto& leds = pcs->GetControlSurfaces()->GetLeadingEdgeDevices()) { for (auto& led : leds->GetLeadingEdgeDevices()) { + auto objs = app->getScene()->GetShapeManager().GetIObjectsFromShapeName(led->GetUID()); + // remove old wireframe flap shapes + for (auto& obj : objs) { + app->getScene()->getContext()->Remove(obj, Standard_True); + app->getScene()->GetShapeManager().removeObject(obj); + } drawWingFlap(led->GetUID().c_str()); } } } app->getScene()->updateViewer(); } + catch (tigl::CTiglError& ex) { displayError(ex.what(), "Error"); return false; @@ -1229,13 +1312,31 @@ void TIGLCreatorDocument::drawWingFlap(const QString& uid) if (*obj.type == typeid(tigl::CCPACSTrailingEdgeDevice)) { auto* ted = static_cast(obj.ptr); app->getScene()->displayShape(ted->GetLoft(), false, Quantity_NOC_GREEN); + + // if flap has mirrored loft, display it too (not mirrored), to later update its transform and then mirror it + PNamedShape mirrored_loft = ted->GetMirroredLoft(); + if (mirrored_loft) { + PNamedShape mirror_named(new CNamedShape(ted->GetLoft()->Shape(), (ted->GetUID() + "M").c_str())); + auto mirror_shape = app->getScene()->displayShape(mirror_named, false, Quantity_NOC_GREEN); + app->getScene()->GetShapeManager().addObject(ted->GetUID(), mirror_shape); + } updateFlapTransform(ted->GetUID()); + } else if (*obj.type == typeid(tigl::CCPACSLeadingEdgeDevice)) { - auto* ted = static_cast(obj.ptr); - app->getScene()->displayShape(ted->GetLoft(), false, Quantity_NOC_GREEN); - updateFlapTransform(ted->GetUID()); + auto* led = static_cast(obj.ptr); + app->getScene()->displayShape(led->GetLoft(), false, Quantity_NOC_GREEN); + + // if flap has mirrored loft, display it too (not mirrored), to later update its transform and then mirror it + PNamedShape mirrored_loft = led->GetMirroredLoft(); + if (mirrored_loft) { + PNamedShape mirror_named(new CNamedShape(led->GetLoft()->Shape(), (led->GetUID() + "M").c_str())); + auto mirror_shape = app->getScene()->displayShape(mirror_named, false, Quantity_NOC_GREEN); + app->getScene()->GetShapeManager().addObject(led->GetUID(), mirror_shape); + + } + updateFlapTransform(led->GetUID()); } } catch (const tigl::CTiglError& ex) { @@ -1249,6 +1350,7 @@ void TIGLCreatorDocument::updateFlapTransform(const std::string& controlUID) gp_Trsf trsf; IObjectList flaps; + IObjectList mflaps; if (*obj.type == typeid(tigl::CCPACSTrailingEdgeDevice)) { auto* controlSurfaceDevice = static_cast(obj.ptr); @@ -1257,6 +1359,8 @@ void TIGLCreatorDocument::updateFlapTransform(const std::string& controlUID) flaps = app->getScene()->GetShapeManager().GetIObjectsFromShapeName(controlSurfaceDevice->GetUID()); + mflaps = + app->getScene()->GetShapeManager().GetIObjectsFromShapeName(controlSurfaceDevice->GetUID()+"M"); } catch (const tigl::CTiglError&) { displayError(QString("Error computing control surface device '%1'").arg(controlUID.c_str()), @@ -1271,20 +1375,78 @@ void TIGLCreatorDocument::updateFlapTransform(const std::string& controlUID) flaps = app->getScene()->GetShapeManager().GetIObjectsFromShapeName(controlSurfaceDevice->GetUID()); + mflaps = + app->getScene()->GetShapeManager().GetIObjectsFromShapeName(controlSurfaceDevice->GetUID()+"M"); } catch (const tigl::CTiglError&) { displayError(QString("Error computing control surface device '%1'").arg(controlUID.c_str()), QString("Error")); } } - + for (const auto& flap : flaps) { app->getScene()->getContext()->SetLocation(flap, trsf); } - + + for (const auto& mflap : mflaps) { + // apply mirroring on transformed flap + tigl::ITiglGeometricComponent& component = GetConfiguration().GetUIDManager().GetGeometricComponent(controlUID); + auto* geometricComp = dynamic_cast(&component); + if (geometricComp) { + TiglSymmetryAxis sym = geometricComp->GetSymmetryAxis(); + if (sym != TIGL_NO_SYMMETRY) { + gp_Trsf mirror_trsf; + tigl::CTiglTransformation trafo(trsf); + if (sym == TIGL_X_Z_PLANE) { + mirror_trsf.SetMirror(gp_Ax2(gp_Pnt(0, 0, 0), gp_Dir(0, 1, 0))); + } + else if (sym == TIGL_X_Y_PLANE) { + mirror_trsf.SetMirror(gp_Ax2(gp_Pnt(0, 0, 0), gp_Dir(0, 0, 1))); + } + else if (sym == TIGL_Y_Z_PLANE) { + mirror_trsf.SetMirror(gp_Ax2(gp_Pnt(0, 0, 0), gp_Dir(1, 0, 0))); + } + + app->getScene()->getContext()->SetLocation(mflap, mirror_trsf * trsf); + + } + } + } + app->getViewer()->update(); } +void TIGLCreatorDocument::removeWingFlaps(const QString& Uid) +{ + tigl::CCPACSWing& wing = GetConfiguration().GetWing(Uid.toStdString()); + + for (int j = 1; j <= wing.GetComponentSegmentCount(); ++j) { + tigl::CCPACSWingComponentSegment& cs = wing.GetComponentSegment(j); + + if (auto& teds = cs.GetControlSurfaces()->GetTrailingEdgeDevices()) { + for (auto& ted : teds->GetTrailingEdgeDevices()) { + auto objs = app->getScene()->GetShapeManager().GetIObjectsFromShapeName(ted->GetUID()); + // remove flap shapes + for (auto& obj : objs) { + app->getScene()->getContext()->Remove(obj, Standard_True); + app->getScene()->GetShapeManager().removeObject(obj); + } + } + } + if (auto& leds = cs.GetControlSurfaces()->GetLeadingEdgeDevices()) { + for (auto& led : leds->GetLeadingEdgeDevices()) { + auto objs = app->getScene()->GetShapeManager().GetIObjectsFromShapeName(led->GetUID()); + // remove flap shapes + for (auto& obj : objs) { + app->getScene()->getContext()->Remove(obj, Standard_True); + app->getScene()->GetShapeManager().removeObject(obj); + } + } + } + } +} + + void TIGLCreatorDocument::drawFuselage() { QString fuselageUid = dlgGetFuselageSelection(); @@ -2239,9 +2401,9 @@ void TIGLCreatorDocument::drawWingShells() } } -void TIGLCreatorDocument::drawWingStructure() +void TIGLCreatorDocument::drawWingStructure(const QString& Uid) { - QString csUid = dlgGetWingComponentSegmentSelection(); + QString csUid = dlgGetWingComponentSegmentSelection(Uid); if (csUid == "") { return; } @@ -2276,10 +2438,17 @@ void TIGLCreatorDocument::drawWingStructure() return; } - app->getScene()->deleteAllObjects(); + auto objects = app->getScene()->GetShapeManager().GetIObjectsFromShapeName(Uid.toStdString()); + for (auto& obj : objects) { + app->getScene()->getContext()->Remove(obj, Standard_False); + app->getScene()->GetShapeManager().removeObject(obj); + } + + removeWingFlaps(Uid); // display component segment shape with transparency - app->getScene()->displayShape(cs.GetLoft(), true, Quantity_NOC_ShapeCol, 0.5); + auto cs_shape = app->getScene()->displayShape(cs.GetLoft(), true, Quantity_NOC_ShapeCol, 0.5); + app->getScene()->GetShapeManager().addObject(Uid.toStdString(), cs_shape); const tigl::CCPACSWingCSStructure& structure = *cs.GetStructure(); @@ -2287,14 +2456,36 @@ void TIGLCreatorDocument::drawWingStructure() for (int ispar = 1; ispar <= structure.GetSparSegmentCount(); ++ispar) { const tigl::CCPACSWingSparSegment& spar = structure.GetSparSegment(ispar); TopoDS_Shape sparGeom = spar.GetSparGeometry(); - app->getScene()->displayShape(sparGeom, true, Quantity_NOC_RED); + auto spar_shape = app->getScene()->displayShape(sparGeom, true, Quantity_NOC_RED); + app->getScene()->GetShapeManager().addObject(Uid.toStdString(), spar_shape); + + PNamedShape loftNamed(new CNamedShape(sparGeom, Uid.toStdString())); + tigl::CCPACSWing& wing = GetConfiguration().GetWing(Uid.toStdString()); + PNamedShape mirroredLoft = wing.GetMirroredLoft(loftNamed); + if (mirroredLoft) + { + auto shape = app->getScene()->displayShape(mirroredLoft, true, getDefaultShapeSymmetryColor()); + app->getScene()->GetShapeManager().addObject(Uid.toStdString(), shape); + + } } // draw ribs for (int irib = 1; irib <= structure.GetRibsDefinitionCount(); ++irib) { const tigl::CCPACSWingRibsDefinition& rib = structure.GetRibsDefinition(irib); TopoDS_Shape ribGeom = rib.GetRibsGeometry(); - app->getScene()->displayShape(ribGeom, true, Quantity_NOC_RED); + auto rib_shape = app->getScene()->displayShape(ribGeom, true, Quantity_NOC_RED); + app->getScene()->GetShapeManager().addObject(Uid.toStdString(), rib_shape); + + PNamedShape loftNamed(new CNamedShape(ribGeom, Uid.toStdString())); + tigl::CCPACSWing& wing = GetConfiguration().GetWing(Uid.toStdString()); + PNamedShape mirroredLoft = wing.GetMirroredLoft(loftNamed); + if (mirroredLoft) + { + auto shape = app->getScene()->displayShape(mirroredLoft, true, getDefaultShapeSymmetryColor()); + app->getScene()->GetShapeManager().addObject(Uid.toStdString(), shape); + + } } } catch (tigl::CTiglError& err) { diff --git a/TIGLCreator/src/TIGLCreatorDocument.h b/TIGLCreator/src/TIGLCreatorDocument.h index f9769293a..f7b451e71 100644 --- a/TIGLCreator/src/TIGLCreatorDocument.h +++ b/TIGLCreator/src/TIGLCreatorDocument.h @@ -93,7 +93,7 @@ public slots: // Wing slots void drawWingProfiles(); - void drawWing(); + void drawWing(const QString& Uid=nullptr); void drawWingOverlayProfilePoints(); void drawWingGuideCurves(); void drawWingTriangulation(); @@ -102,8 +102,8 @@ public slots: void drawWingComponentSegment(); void drawWingComponentSegmentPoints(); void drawWingShells(); - void drawWingFlaps(); - void drawWingStructure(); + void drawWingFlaps(const QString& wingUID=nullptr); + void drawWingStructure(const QString& wingUID=nullptr); // Fuselage slots void drawFuselageProfiles(); @@ -164,7 +164,7 @@ private slots: // Wing selection dialogs QString dlgGetWingOrRotorBladeSelection(); QString dlgGetWingSelection(); - QString dlgGetWingComponentSegmentSelection(); + QString dlgGetWingComponentSegmentSelection(const QString& wingUID=nullptr); QString dlgGetWingSegmentSelection(); QString dlgGetWingProfileSelection(); @@ -216,6 +216,7 @@ private slots: void drawWingShells(tigl::CCPACSWing& wing); bool drawWingFlaps(tigl::CCPACSWing& wing); void drawWingFlap(const QString& flapUID); + void removeWingFlaps(const QString& Uid); void createShapeTriangulation(const class TopoDS_Shape& shape, class TopoDS_Compound& compound); diff --git a/TIGLCreator/src/modificators/ModificatorDisplayOptionsWidget.cpp b/TIGLCreator/src/modificators/ModificatorDisplayOptionsWidget.cpp index 59d85382f..1df095470 100644 --- a/TIGLCreator/src/modificators/ModificatorDisplayOptionsWidget.cpp +++ b/TIGLCreator/src/modificators/ModificatorDisplayOptionsWidget.cpp @@ -31,6 +31,7 @@ #include "../TIGLCreatorContext.h" #include "ui_ModificatorDisplayOptionsWidget.h" #include +#include "TIGLCreatorWindow.h" #define BTN_STYLE "#%2 {background-color: %1; color: black; border: 1px solid black; border-radius: 5px;} #%2:hover {border: 1px solid white;}" @@ -56,7 +57,7 @@ ModificatorDisplayOptionsWidget::ModificatorDisplayOptionsWidget(QWidget* parent materialCombo->addItem(kv.first); } - // interactions + // General Display Options connect(transparencySlider, SIGNAL(valueChanged(int)), this, SLOT(onTransparencyChanged(int))); connect(renderingModeCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(onRenderingModeChanged(int))); connect(materialCombo, SIGNAL(currentTextChanged(const QString &)), this, SLOT(onMaterialChanged(const QString &))); @@ -81,21 +82,23 @@ void ModificatorDisplayOptionsWidget::setFromItem(cpcr::CPACSTreeItem* item, TIG ui->transparencySlider->setVisible(false); ui->labelRenderingMode->setVisible(false); ui->renderingModeCombo->setVisible(false); + ui->labelColor->setVisible(false); ui->buttonColorChoser->setVisible(false); - ui->label_color->setVisible(false); + ui->labelColor->setVisible(false); ui->labelMaterial->setVisible(false); ui->materialCombo->setVisible(false); ui->buttonResetOptions->setVisible(false); + ui->drawOptionsCombo->setVisible(false); } currentItem = nullptr; return; } if (item) { - if ((!item->getUid().empty() && doc->GetConfiguration().GetUIDManager().HasGeometricComponent(item->getUid()))) { - auto uid = item->getUid(); + const QString uid = QString::fromStdString(item->getUid()); + if ((!uid.isEmpty() && doc->GetConfiguration().GetUIDManager().HasGeometricComponent(uid.toStdString()))) { const auto& shapes = doc->GetConfiguration().GetUIDManager().GetShapeContainer(); - auto it = shapes.find(uid); + auto it = shapes.find(uid.toStdString()); if (it != shapes.end() && it->second != nullptr) { tigl::ITiglGeometricComponent* comp = it->second; if (comp->GetComponentType() != TIGL_COMPONENT_PLANE && comp->GetComponentType() != TIGL_COMPONENT_CROSS_BEAM_STRUT) { @@ -105,15 +108,14 @@ void ModificatorDisplayOptionsWidget::setFromItem(cpcr::CPACSTreeItem* item, TIG ui->transparencySlider->setVisible(true); ui->labelRenderingMode->setVisible(true); ui->renderingModeCombo->setVisible(true); - ui->label_color->setVisible(true); + ui->labelColor->setVisible(true); ui->buttonColorChoser->setVisible(true); ui->labelMaterial->setVisible(true); ui->materialCombo->setVisible(true); ui->buttonResetOptions->setVisible(true); + ui->drawOptionsCombo->setVisible(true); } - - const QString type = QString::fromStdString(item->getType()); - const QString uid = QString::fromStdString(item->getUid()); + // get current values @@ -152,13 +154,70 @@ void ModificatorDisplayOptionsWidget::setFromItem(cpcr::CPACSTreeItem* item, TIG ui->labelRenderingMode->setVisible(false); ui->renderingModeCombo->setVisible(false); ui->buttonColorChoser->setVisible(false); - ui->label_color->setVisible(false); + ui->labelColor->setVisible(false); ui->labelMaterial->setVisible(false); ui->materialCombo->setVisible(false); ui->buttonResetOptions->setVisible(false); + ui->drawOptionsCombo->setVisible(false); } } - } + + + // Populate draw options combo when the selected item is a wing (type or uid == "wing"). + ui->drawOptionsCombo->clear(); + drawCallbacks.clear(); + if (!uid.isEmpty() && doc->GetConfiguration().GetUIDManager().HasGeometricComponent(uid.toStdString())) { + auto type = doc->GetConfiguration().GetUIDManager().GetGeometricComponent(uid.toStdString()).GetComponentType(); + + if (type == TIGL_COMPONENT_WING) { + // Add entries and store callbacks that call the document drawing functions + ui->drawOptionsCombo->addItem(tr("Wing")); + drawCallbacks.push_back([doc, uid]() { if (doc) doc->drawWing(uid); }); + + ui->drawOptionsCombo->addItem(tr("Profiles")); + drawCallbacks.push_back([doc]() { if (doc) doc->drawWingProfiles(); }); + + ui->drawOptionsCombo->addItem(tr("Overlay profile points")); + drawCallbacks.push_back([doc]() { if (doc) doc->drawWingOverlayProfilePoints(); }); + + ui->drawOptionsCombo->addItem(tr("Guide curves")); + drawCallbacks.push_back([doc]() { if (doc) doc->drawWingGuideCurves(); }); + + ui->drawOptionsCombo->addItem(tr("Triangulation")); + drawCallbacks.push_back([doc]() { if (doc) doc->drawWingTriangulation(); }); + + ui->drawOptionsCombo->addItem(tr("Sample points")); + drawCallbacks.push_back([doc]() { if (doc) doc->drawWingSamplePoints(); }); + + ui->drawOptionsCombo->addItem(tr("Fused wing")); + drawCallbacks.push_back([doc]() { if (doc) doc->drawFusedWing(); }); + + ui->drawOptionsCombo->addItem(tr("Component segment")); + drawCallbacks.push_back([doc]() { if (doc) doc->drawWingComponentSegment(); }); + + ui->drawOptionsCombo->addItem(tr("Component segment points")); + drawCallbacks.push_back([doc]() { if (doc) doc->drawWingComponentSegmentPoints(); }); + + ui->drawOptionsCombo->addItem(tr("Shells")); + drawCallbacks.push_back([doc]() { if (doc) doc->drawWingShells(); }); + + ui->drawOptionsCombo->addItem(tr("Structure")); + drawCallbacks.push_back([doc, uid]() { if (doc) doc->drawWingStructure(uid); }); + + ui->drawOptionsCombo->addItem(tr("Flaps")); + drawCallbacks.push_back([doc, uid]() { if (doc) doc->drawWingFlaps(uid); }); + + // Trigger the corresponding callback when an item is activated. Use UniqueConnection to avoid duplicate connections. + connect(ui->drawOptionsCombo, QOverload::of(&QComboBox::activated), this, + [this](int idx) { + if (idx >= 0 && idx < static_cast(drawCallbacks.size()) && drawCallbacks[idx]) { + drawCallbacks[idx](); + } + }, Qt::UniqueConnection); + } + } + } + } bool ModificatorDisplayOptionsWidget::apply() @@ -417,9 +476,22 @@ void ModificatorDisplayOptionsWidget::onResetOptions() // redraw component to reset options (necessary to reset different colors on mirrored components) context->Remove(obj, Standard_False); sm.removeObject(obj); - currentDoc->drawComponentByUID(uid); + } } + + auto type = currentDoc->GetConfiguration().GetUIDManager().GetGeometricComponent(uid.toStdString()).GetComponentType(); + if (type == TIGL_COMPONENT_WING) { + tigl::CCPACSWing& wing = currentDoc->GetConfiguration().GetWing(uid.toStdString()); + wing.SetBuildFlaps(false); + currentDoc->drawWing(uid); + + } + + else { + currentDoc->drawComponentByUID(uid); + } + if (!currentContext->getContext().IsNull()) { currentContext->updateViewer(); } diff --git a/TIGLCreator/src/modificators/ModificatorDisplayOptionsWidget.h b/TIGLCreator/src/modificators/ModificatorDisplayOptionsWidget.h index cb6742a71..1f9154b63 100644 --- a/TIGLCreator/src/modificators/ModificatorDisplayOptionsWidget.h +++ b/TIGLCreator/src/modificators/ModificatorDisplayOptionsWidget.h @@ -35,6 +35,9 @@ class QButtonGroup; class QPushButton; class QComboBox; class QColor; +// callbacks used for draw options (avoid direct QAction dependency) +#include +#include class ModificatorDisplayOptionsWidget : public CpacsEditorBase { @@ -74,6 +77,9 @@ private slots: QComboBox* materialCombo{nullptr}; QPushButton* buttonResetOptions{nullptr}; + // Callbacks mapped to indices of ui->drawOptionsCombo (used for wing draw options) + std::vector> drawCallbacks; + cpcr::CPACSTreeItem* currentItem{nullptr}; TIGLCreatorDocument* currentDoc{nullptr}; TIGLCreatorContext* currentContext{nullptr}; diff --git a/TIGLCreator/src/modificators/ModificatorDisplayOptionsWidget.ui b/TIGLCreator/src/modificators/ModificatorDisplayOptionsWidget.ui index 863c7d10d..acf06ad05 100644 --- a/TIGLCreator/src/modificators/ModificatorDisplayOptionsWidget.ui +++ b/TIGLCreator/src/modificators/ModificatorDisplayOptionsWidget.ui @@ -66,7 +66,7 @@ - + Color: @@ -107,22 +107,26 @@ - - - - Draw Options: - - - false - - - - - - false - - + + + + + Material: + + + false + + + + + + + false + + + + diff --git a/src/wing/CCPACSWing.cpp b/src/wing/CCPACSWing.cpp index 09347ebea..6eebe56ae 100644 --- a/src/wing/CCPACSWing.cpp +++ b/src/wing/CCPACSWing.cpp @@ -64,6 +64,7 @@ #include #include #include +#include "CNamedShape.h" #include "CTiglLogging.h" #include #include @@ -305,6 +306,39 @@ CCPACSWingComponentSegment& CCPACSWing::GetComponentSegment(const std::string& u return m_componentSegments->GetComponentSegment(uid); } +PNamedShape CCPACSWing::GetMirroredLoft(PNamedShape input_shape) const +{ + if (!input_shape) { + input_shape = GetLoft(); + } + const TiglSymmetryAxis& symmetryAxis = GetSymmetryAxis(); + if (symmetryAxis == TIGL_NO_SYMMETRY) { + return PNamedShape(); + } + + CTiglTransformation trafo; + if (symmetryAxis == TIGL_X_Z_PLANE) { + trafo.AddMirroringAtXZPlane(); + } + else if (symmetryAxis == TIGL_X_Y_PLANE) { + trafo.AddMirroringAtXYPlane(); + } + else if (symmetryAxis == TIGL_Y_Z_PLANE) { + trafo.AddMirroringAtYZPlane(); + } + + PNamedShape mirroredShape = trafo.Transform(input_shape); + + std::string mirrorName = mirroredShape->Name(); + mirrorName += "M"; + std::string mirrorShortName = mirroredShape->ShortName(); + mirrorShortName += "M"; + mirroredShape->SetName(mirrorName.c_str()); + mirroredShape->SetShortName(mirrorShortName.c_str()); + return mirroredShape; +} + + // Gets the loft of the whole wing with modeled leading edge. TopoDS_Shape& CCPACSWing::GetLoftWithLeadingEdge() { diff --git a/src/wing/CCPACSWing.h b/src/wing/CCPACSWing.h index 94788ccb0..8ca9ccbb3 100644 --- a/src/wing/CCPACSWing.h +++ b/src/wing/CCPACSWing.h @@ -174,6 +174,12 @@ friend class CTiglWingBuilder; */ TIGL_EXPORT CCPACSWingComponentSegment& GetComponentSegment(const std::string& uid); + /** + * @brief Returns the mirrored loft at the wings symmetry plane + * @param input_shape Shape to be mirrored with the wings symmetry + * @return PNamedShape + */ + TIGL_EXPORT PNamedShape GetMirroredLoft(PNamedShape input_shape = nullptr) const; /** * @brief Returns the positioning transformation for a given section uid * @param sectionUID