// Copyright (c) 2020 OPEN CASCADE SAS // // This file is part of the examples of the Open CASCADE Technology software library. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE #include "OcafSamples.h" #include "TOcaf_Application.h" #include "TOcafFunction_BoxDriver.h" #include "TOcafFunction_CylDriver.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include void OcafSamples::Process (const TCollection_AsciiString& theSampleName) { if (IsImportSample(theSampleName)) { myObject3d.Clear(); } myObject2d.Clear(); myCode.Clear(); myIsProcessed = Standard_False; try { ExecuteSample(theSampleName); } catch (...) { TraceError(TCollection_AsciiString("Error in sample: ") + theSampleName); } } void OcafSamples::ClearExtra() { myOcafDoc = nullptr; myContext->RemoveAll(Standard_True); } void OcafSamples::ExecuteSample (const TCollection_AsciiString& theSampleName) { Standard_Boolean anIsSamplePresent = Standard_True; FindSourceCode(theSampleName); if (theSampleName == "CreateOcafDocument") CreateOcafDocument(); else if (theSampleName == "CreateBoxOcafSample") CreateBoxOcafSample(); else if (theSampleName == "CreateCylinderOcafSample") CreateCylinderOcafSample(); else if (theSampleName == "ModifyBoxOcafSample") ModifyBoxOcafSample(); else if (theSampleName == "ModifyCylinderOcafSample") ModifyCylinderOcafSample(); else if (theSampleName == "UndoOcafSample") UndoOcafSample(); else if (theSampleName == "RedoOcafSample") RedoOcafSample(); else if (theSampleName == "DialogOpenOcafSample") DialogOpenOcafSample(); else if (theSampleName == "DialogSaveBinOcafSample") DialogSaveBinOcafSample(); else if (theSampleName == "DialogSaveXmlOcafSample") DialogSaveXmlOcafSample(); else { myResult << "No function found: " << theSampleName; myCode += TCollection_AsciiString("No function found: ") + theSampleName; anIsSamplePresent = Standard_False; } myIsProcessed = anIsSamplePresent; } Standard_Boolean OcafSamples::IsExportSample (const TCollection_AsciiString& theSampleName) { if (theSampleName == "DialogSaveBinOcafSample" || theSampleName == "DialogSaveXmlOcafSample") { return Standard_True; } else { return Standard_False; } } Standard_Boolean OcafSamples::IsImportSample (const TCollection_AsciiString& theSampleName) { if (theSampleName == "DialogOpenOcafSample") { return Standard_True; } else { return Standard_False; } } Standard_Boolean OcafSamples::IsBinarySample (const TCollection_AsciiString& theSampleName) { if (theSampleName == "DialogOpenOcafSample" || theSampleName == "DialogSaveBinOcafSample") { return Standard_True; } else { return Standard_False; } } Standard_Boolean OcafSamples::IsXmlSample (const TCollection_AsciiString& theSampleName) { if (theSampleName == "DialogOpenOcafSample" || theSampleName == "DialogSaveXmlOcafSample") { return Standard_True; } else { return Standard_False; } } void OcafSamples::CreateOcafDocument() { Handle(TOcaf_Application) anOcaf_Application = new TOcaf_Application; anOcaf_Application->NewDocument("BinOcaf", myOcafDoc); TPrsStd_AISViewer::New(myOcafDoc->Main(), myViewer); Handle(AIS_InteractiveContext) anAisContext; TPrsStd_AISViewer::Find(myOcafDoc->Main(), anAisContext); anAisContext->SetDisplayMode(AIS_Shaded, Standard_True); myContext = anAisContext; // Set the maximum number of available "undo" actions myOcafDoc->SetUndoLimit(10); } void OcafSamples::CreateBoxOcafSample() { // Open a new command (for undo) myOcafDoc->NewCommand(); // A data structure for our box: // the box itself is attached to the BoxLabel label (as his name and his function attribute) // its arguments (dimensions: width, length and height; and position: x, y, z) // are attached to the child labels of the box: // 0:1 Box Label ---> Name ---> Named shape ---> Function // 0:1:1 -- Width Label // 0:1:2 -- Length Label // 0:1:3 -- Height Label // 0:1:4 -- X Label // 0:1:5 -- Y Label // 0:1:6 -- Z Label // Create a new label in the data structure for the box TDF_Label aLabel = TDF_TagSource::NewChild(myOcafDoc->Main()); Standard_Real aBoxWidth(30.0), aBoxLength(20.0), aBoxHeight(10.0); Standard_Real aBoxX(0.0), aBoxY(0.0), aBoxZ(0.0); Standard_CString aBoxName("OcafBox"); // Create the data structure : Set the dimensions, position and name attributes TDataStd_Real::Set(aLabel.FindChild(1), aBoxWidth); TDataStd_Real::Set(aLabel.FindChild(2), aBoxLength); TDataStd_Real::Set(aLabel.FindChild(3), aBoxHeight); TDataStd_Real::Set(aLabel.FindChild(4), aBoxX); TDataStd_Real::Set(aLabel.FindChild(5), aBoxY); TDataStd_Real::Set(aLabel.FindChild(6), aBoxZ); TDataStd_Name::Set(aLabel, aBoxName); // Name // Instantiate a TFunction_Function attribute connected to the current box driver // and attach it to the data structure as an attribute of the Box Label Handle(TFunction_Function) myFunction = TFunction_Function::Set(aLabel, TOcafFunction_BoxDriver::GetID()); // Initialize and execute the box driver (look at the "Execute()" code) Handle(TFunction_Logbook) aLogBook = TFunction_Logbook::Set(aLabel); Handle(TFunction_Driver) myBoxDriver; // Find the TOcafFunction_BoxDriver in the TFunction_DriverTable using its GUID if (!TFunction_DriverTable::Get()->FindDriver(TOcafFunction_BoxDriver::GetID(), myBoxDriver)) { myResult << "Ocaf Box driver not found" << std::endl; } myBoxDriver->Init(aLabel); if (myBoxDriver->Execute(aLogBook)) { myResult << "Create Box function execute failed" << std::endl; } // Get the TPrsStd_AISPresentation of the new box TNaming_NamedShape Handle(TPrsStd_AISPresentation) anAisPresentation = TPrsStd_AISPresentation::Set(aLabel, TNaming_NamedShape::GetID()); // Display it anAisPresentation->Display(1); // Attach an integer attribute to aLabel to memorize it's displayed TDataStd_Integer::Set(aLabel, 1); myContext->UpdateCurrentViewer(); // Close the command (for undo) myOcafDoc->CommitCommand(); myResult << "Created a box with name: " << aBoxName << std::endl; myResult << "base coord X: " << aBoxX << " Y: " << aBoxY << " Z: " << aBoxZ << std::endl; myResult << "width: " << aBoxWidth << " length: " << aBoxLength << " height: " << aBoxHeight << std::endl; } void OcafSamples::CreateCylinderOcafSample() { // Open a new command (for undo) myOcafDoc->NewCommand(); // A data structure for our cylinder: // the cylinder itself is attached to the CylinderLabel label (as his name and his function attribute) // its arguments (dimensions: radius and height; and position: x, y, z) // are attached to the child labels of the cylinder: // 0:1 Cylinder Label ---> Name ---> Named shape ---> Function // 0:1:1 -- Radius Label // 0:1:2 -- Height Label // 0:1:3 -- X Label // 0:1:4 -- Y Label // 0:1:5 -- Z Label // Create a new label in the data structure for the cylinder TDF_Label aLabel = TDF_TagSource::NewChild(myOcafDoc->Main()); Standard_Real aCylRadius(10.0), aCylHeight(20.0); Standard_Real aCylX(60.0), aCylY(40.0), aCylZ(0.0); Standard_CString aCylName("OcafCylinder"); // Create the data structure : Set the dimensions, position and name attributes TDataStd_Real::Set(aLabel.FindChild(1), aCylRadius); TDataStd_Real::Set(aLabel.FindChild(2), aCylHeight); TDataStd_Real::Set(aLabel.FindChild(3), aCylX); TDataStd_Real::Set(aLabel.FindChild(4), aCylY); TDataStd_Real::Set(aLabel.FindChild(5), aCylZ); TDataStd_Name::Set(aLabel, aCylName); // Instantiate a TFunction_Function attribute connected to the current cylinder driver // and attach it to the data structure as an attribute of the Cylinder Label Handle(TFunction_Function) myFunction = TFunction_Function::Set(aLabel, TOcafFunction_CylDriver::GetID()); // Initialize and execute the cylinder driver (look at the "Execute()" code) Handle(TFunction_Logbook) aLogBook = TFunction_Logbook::Set(aLabel); Handle(TFunction_Driver) myCylDriver; // Find the TOcafFunction_CylDriver in the TFunction_DriverTable using its GUID if (!TFunction_DriverTable::Get()->FindDriver(TOcafFunction_CylDriver::GetID(), myCylDriver)) { myResult << "Ocaf Cylinder driver not found"; } myCylDriver->Init(aLabel); if (myCylDriver->Execute(aLogBook)) { myResult << "Create Cylinder function execute failed"; } // Get the TPrsStd_AISPresentation of the new box TNaming_NamedShape Handle(TPrsStd_AISPresentation) anAisPresentation = TPrsStd_AISPresentation::Set(aLabel, TNaming_NamedShape::GetID()); // Display it anAisPresentation->Display(1); // Attach an integer attribute to aLabel to memorize it's displayed TDataStd_Integer::Set(aLabel, 1); myContext->UpdateCurrentViewer(); // Close the command (for undo) myOcafDoc->CommitCommand(); myResult << "Created a cylinder with name: " << aCylName << std::endl; myResult << "radius: " << aCylRadius << " height: " << aCylHeight << std::endl; myResult << "base coord X: " << aCylX << " Y: " << aCylY << " Z: " << aCylZ << std::endl; } void OcafSamples::ModifyBoxOcafSample() { AIS_ListOfInteractive anAisObjectsList; myContext->DisplayedObjects(anAisObjectsList); Standard_Integer aBoxCount(0); for(AIS_ListOfInteractive::Iterator anIter(anAisObjectsList); anIter.More(); anIter.Next()) { const Handle(AIS_InteractiveObject)& anAisObject = anIter.Value(); // Get the main label of the selected object Handle(TPrsStd_AISPresentation) anAisPresentation = Handle(TPrsStd_AISPresentation)::DownCast(anAisObject->GetOwner()); TDF_Label aLabel = anAisPresentation->Label(); // Get the TFunction_Function attribute of the selected object Handle(TFunction_Function) aFunction; if (!aLabel.FindAttribute(TFunction_Function::GetID(), aFunction)) { myResult << "Object cannot be modified."; return; } // Get the Standard_GUID of the TFunction_FunctionDriver of the selected object TFunction_Function attribute Standard_GUID aDriverID = aFunction->GetDriverGUID(); // Case of a box created with the box function driver if (aDriverID == TOcafFunction_BoxDriver::GetID()) { aBoxCount++; Standard_Real aBoxX, aBoxY, aBoxZ, aBoxWidth, aBoxLength, aBoxHeight; // Get the attributes values of the current box Handle(TDataStd_Real) aCurrentReal; aLabel.FindChild(1).FindAttribute(TDataStd_Real::GetID(), aCurrentReal); aBoxWidth = aCurrentReal->Get(); aLabel.FindChild(2).FindAttribute(TDataStd_Real::GetID(), aCurrentReal); aBoxLength = aCurrentReal->Get(); aLabel.FindChild(3).FindAttribute(TDataStd_Real::GetID(), aCurrentReal); aBoxHeight = aCurrentReal->Get(); aLabel.FindChild(4).FindAttribute(TDataStd_Real::GetID(), aCurrentReal); aBoxX = aCurrentReal->Get(); aLabel.FindChild(5).FindAttribute(TDataStd_Real::GetID(), aCurrentReal); aBoxY = aCurrentReal->Get(); aLabel.FindChild(6).FindAttribute(TDataStd_Real::GetID(), aCurrentReal); aBoxZ = aCurrentReal->Get(); Handle(TDataStd_Name) aBoxName; aLabel.FindAttribute(TDataStd_Name::GetID(), aBoxName); myResult << "Current parameters of box with name: " << aBoxName->Get() << std::endl; myResult << "width: " << aBoxWidth << " length: " << aBoxLength << " height: " << aBoxHeight << std::endl; myResult << "base coord X: " << aBoxX << " Y: " << aBoxY << " Z: " << aBoxZ << std::endl; // Open a new command (for undo) myOcafDoc->NewCommand(); // Modify the box - 1.5 times increase aBoxWidth *= 1.5; aBoxLength *= 1.5; aBoxHeight *= 1.5; TDataStd_Real::Set(aLabel.FindChild(1), aBoxWidth); TDataStd_Real::Set(aLabel.FindChild(2), aBoxLength); TDataStd_Real::Set(aLabel.FindChild(3), aBoxHeight); TDataStd_Real::Set(aLabel.FindChild(4), aBoxX); TDataStd_Real::Set(aLabel.FindChild(5), aBoxY); TDataStd_Real::Set(aLabel.FindChild(6), aBoxZ); // Get the TFunction_FunctionDriver GUID used with the TFunction_Function aDriverID = aFunction->GetDriverGUID(); Handle(TFunction_Logbook) aLogBook = TFunction_Logbook::Set(aLabel); Handle(TFunction_Driver) aBoxDriver; // Find the TOcafFunction_BoxDriver in the TFunction_DriverTable using its GUID TFunction_DriverTable::Get()->FindDriver(aDriverID, aBoxDriver); // Execute the cut if it must be (if an attribute changes) aBoxDriver->Init(aLabel); // Set the box touched, it will be useful to recompute an object which used this box as attribute aLogBook->SetTouched(aLabel); if (aBoxDriver->Execute(aLogBook)) { myResult << "Recompute failed" << std::endl; } // Get the presentation of the box, display it and set it selected anAisPresentation = TPrsStd_AISPresentation::Set(aLabel, TNaming_NamedShape::GetID()); TDataStd_Integer::Set(aLabel, 1); anAisPresentation->Display(1); myContext->UpdateCurrentViewer(); // Close the command (for undo) myOcafDoc->CommitCommand(); myResult << std::endl; myResult << "New box parameters: " << std::endl; myResult << "base coord X: " << aBoxX << " Y: " << aBoxY << " Z: " << aBoxZ << std::endl; myResult << "width: " << aBoxWidth << " length: " << aBoxLength << " height: " << aBoxHeight << std::endl; } } if (aBoxCount) { myResult << "Number of modified boxes: " << aBoxCount << std::endl; } else { myResult << "No boxes to modify" << std::endl; } } void OcafSamples::ModifyCylinderOcafSample() { AIS_ListOfInteractive anAisObjectsList; myContext->DisplayedObjects(anAisObjectsList); Standard_Integer aCylCount(0); for(AIS_ListOfInteractive::Iterator anIter (anAisObjectsList); anIter.More(); anIter.Next()) { const Handle(AIS_InteractiveObject)& anAisObject = anIter.Value(); // Get the main label of the selected object Handle(TPrsStd_AISPresentation) anAisPresentation = Handle(TPrsStd_AISPresentation)::DownCast(anAisObject->GetOwner()); TDF_Label aLabel = anAisPresentation->Label(); // Get the TFunction_Function attribute of the selected object Handle(TFunction_Function) aFunction; if (!aLabel.FindAttribute(TFunction_Function::GetID(), aFunction)) { myResult << "Object cannot be modified."; return; } // Get the Standard_GUID of the TFunction_FunctionDriver of the selected object TFunction_Function attribute Standard_GUID aDriverID = aFunction->GetDriverGUID(); // Case of a box created with the box function driver if (aDriverID == TOcafFunction_CylDriver::GetID()) { aCylCount++; Standard_Real aCylRadius, aCylHeight, aCylX, aCylY, aCylZ; // Get the attributes values of the current box Handle(TDataStd_Real) aCurrentReal; aLabel.FindChild(1).FindAttribute(TDataStd_Real::GetID(), aCurrentReal); aCylRadius = aCurrentReal->Get(); aLabel.FindChild(2).FindAttribute(TDataStd_Real::GetID(), aCurrentReal); aCylHeight = aCurrentReal->Get(); aLabel.FindChild(3).FindAttribute(TDataStd_Real::GetID(), aCurrentReal); aCylX = aCurrentReal->Get(); aLabel.FindChild(4).FindAttribute(TDataStd_Real::GetID(), aCurrentReal); aCylY = aCurrentReal->Get(); aLabel.FindChild(5).FindAttribute(TDataStd_Real::GetID(), aCurrentReal); aCylZ = aCurrentReal->Get(); Handle(TDataStd_Name) aCylName; aLabel.FindAttribute(TDataStd_Name::GetID(), aCylName); myResult << "Current parameters of box with name: " << aCylName->Get() << std::endl; myResult << "radius: " << aCylRadius << " height: " << aCylHeight << std::endl; myResult << "base coord X: " << aCylX << " Y: " << aCylY << " Z: " << aCylZ << std::endl; // Open a new command (for undo) myOcafDoc->NewCommand(); // Modify the cylinder - 2x increase aCylRadius *= 2.0; aCylHeight *= 2.0; // and move base point in XY plane aCylX *= 2.0; aCylY *= 2.0; TDataStd_Real::Set(aLabel.FindChild(1), aCylRadius); TDataStd_Real::Set(aLabel.FindChild(2), aCylHeight); TDataStd_Real::Set(aLabel.FindChild(3), aCylX); TDataStd_Real::Set(aLabel.FindChild(4), aCylY); TDataStd_Real::Set(aLabel.FindChild(5), aCylZ); // Get the TFunction_FunctionDriver GUID used with the TFunction_Function aDriverID = aFunction->GetDriverGUID(); Handle(TFunction_Logbook) aLogBook = TFunction_Logbook::Set(aLabel); Handle(TFunction_Driver) aCylDriver; // Find the TOcafFunction_CylDriver in the TFunction_DriverTable using its GUID TFunction_DriverTable::Get()->FindDriver(aDriverID, aCylDriver); // Execute the cut if it must be (if an attribute changes) aCylDriver->Init(aLabel); // Set the cylinder touched, it will be useful to recompute an object which used this box as attribute aLogBook->SetTouched(aLabel); if (aCylDriver->Execute(aLogBook)) { myResult << "Recompute failed" << std::endl; } // Get the presentation of the box, display it and set it selected anAisPresentation = TPrsStd_AISPresentation::Set(aLabel, TNaming_NamedShape::GetID()); TDataStd_Integer::Set(aLabel, 1); anAisPresentation->Display(1); myContext->UpdateCurrentViewer(); // Close the command (for undo) myOcafDoc->CommitCommand(); myResult << std::endl; myResult << "New cylinder parameters: " << std::endl; myResult << "radius: " << aCylRadius << " height: " << aCylHeight << std::endl; myResult << "base coord X: " << aCylX << " Y: " << aCylY << " Z: " << aCylZ << std::endl; } } if (aCylCount) { myResult << "Number of modified boxes: " << aCylCount << std::endl; } else { myResult << "No boxes to modify" << std::endl; } } void OcafSamples::UndoOcafSample() { if (myOcafDoc->Undo()) { myOcafDoc->CommitCommand(); myContext->UpdateCurrentViewer(); myResult << "Undo was done successfully" << std::endl; } else { myResult << "Nothing to undo" << std::endl; } } void OcafSamples::RedoOcafSample() { if (myOcafDoc->Redo()) { myOcafDoc->CommitCommand(); myContext->UpdateCurrentViewer(); myResult << "Redo was done successfully" << std::endl; } else { myResult << "Nothing to redo" << std::endl; } } void OcafSamples::DialogOpenOcafSample() { Handle(TOcaf_Application) anOcaf_Application = new TOcaf_Application; // load persistence BinDrivers::DefineFormat(anOcaf_Application); XmlDrivers::DefineFormat(anOcaf_Application); // Look for already opened if (anOcaf_Application->IsInSession(myFileName)) { myResult << "Document: " << myFileName << " is already in session" << std::endl; return; } // Open the document in the current application PCDM_ReaderStatus aReaderStatus = anOcaf_Application->Open(myFileName, myOcafDoc); if (aReaderStatus == PCDM_RS_OK) { // Connect the document CAF (myDoc) with the AISContext (myAISContext) TPrsStd_AISViewer::New(myOcafDoc->Main(), myViewer); myOcafDoc->SetUndoLimit(10); myContext->RemoveAll(Standard_False); Handle(AIS_InteractiveContext) aContext; TPrsStd_AISViewer::Find(myOcafDoc->Main(), aContext); aContext->SetDisplayMode(AIS_Shaded, Standard_True); myContext = aContext; // Display the presentations (which was not stored in the document) DisplayPresentation(); myResult << "Open a document" << std::endl; } else { myResult << "Error! The file wasn't opened. PCDM_ReaderStatus: " << aReaderStatus << std::endl; } } void OcafSamples::DialogSaveBinOcafSample() { Handle(TOcaf_Application) anOcaf_Application = new TOcaf_Application; BinDrivers::DefineFormat(anOcaf_Application); myOcafDoc->ChangeStorageFormat("BinOcaf"); // Saves the document in the current application PCDM_StoreStatus aStoreStatus = anOcaf_Application->SaveAs(myOcafDoc, myFileName); if (aStoreStatus == PCDM_SS_OK) { myResult << "The file was saved successfully" << std::endl; } else { myResult << "Error! The file wasn't saved. PCDM_StoreStatus: " << aStoreStatus << std::endl; } } void OcafSamples::DialogSaveXmlOcafSample() { Handle(TOcaf_Application) anOcaf_Application = new TOcaf_Application; XmlDrivers::DefineFormat(anOcaf_Application); myOcafDoc->ChangeStorageFormat("XmlOcaf"); // Saves the document in the current application PCDM_StoreStatus aStoreStatus = anOcaf_Application->SaveAs(myOcafDoc, myFileName); if (aStoreStatus == PCDM_SS_OK) { myResult << "The file was saved successfully" << std::endl; } else { myResult << "Error! The file wasn't saved. PCDM_StoreStatus: " << aStoreStatus << std::endl; } } void OcafSamples::DisplayPresentation() { TDF_Label aRootlabel = myOcafDoc->Main(); for (TDF_ChildIterator it(aRootlabel); it.More(); it.Next()) { TDF_Label aLabel = it.Value(); Handle(TNaming_NamedShape) aNamedShape; if (!aLabel.FindAttribute(TNaming_NamedShape::GetID(), aNamedShape)) { continue; } Handle(TDataStd_Integer) aDataInteger; // To know if the object was displayed if (aLabel.FindAttribute(TDataStd_Integer::GetID(), aDataInteger)) { if (!aDataInteger->Get()) { continue; } } Handle(TPrsStd_AISPresentation) anAisPresentation; if (!aLabel.FindAttribute(TPrsStd_AISPresentation::GetID(), anAisPresentation)) { anAisPresentation = TPrsStd_AISPresentation::Set(aLabel, TNaming_NamedShape::GetID()); } anAisPresentation->SetColor(Quantity_NOC_ORANGE); anAisPresentation->Display(1); } myContext->UpdateCurrentViewer(); }