/** * \file Persistence.cpp * * \brief See how entities or attributes on entities are maintained * across modeling operations such as webcut. * * This cuts the 62_shaver1.brep OpenCascade model into two pieces * with the z=40 plane. Both pieces are written to the same * output polydata file. * * Three faces (0, 26, and 149) are observed and all generate * notification events on the "StupidObserver" instance we create, * even though only face 26 is intersected by the cutting plane. * * Also, it's unclear how memory management of observers/observed * geometry is handled; do the observers remove destroyed * geometry from their list automagically or must we take * care to unregister notifications on each observed entity? */ #undef NDEBUG #include #include "stdio.h" #include "GMem.hpp" #include "GeometryQueryTool.hpp" #include "GeometryModifyTool.hpp" #include "RefEdge.hpp" #include "RefFace.hpp" #include "Body.hpp" #include "CubitDefines.h" #include "CubitBox.hpp" #include "InitCGMA.hpp" #include "TestUtilities.hpp" #include "vtkNew.h" #include "vtkPoints.h" #include "vtkPolyData.h" #include "vtkCellArray.h" #include "vtkCellData.h" #include "vtkXMLPolyDataWriter.h" #ifndef SRCDIR # define SRCDIR . #endif #define TEST_OCC #ifdef TEST_ACIS # define ENGINE "ACIS" #elif defined (TEST_OCC) # define ENGINE "OCC" #else # error "Which engine to test?" #endif class StupidObserver : public CubitObserver { public: static StupidObserver* ofEntity(RefEntity* ent) { DLIList list; StupidObserver* eo = NULL; ent->get_observer_list(list); for (int i = list.size(); !eo && i--; ) { eo = dynamic_cast(list.step_and_get()); } return eo; } virtual bool observingEntity(RefEntity* ent) { DLIList list; StupidObserver* eo = NULL; ent->get_observer_list(list); for (int i = list.size(); !eo && i--; ) { eo = dynamic_cast(list.step_and_get()); if (eo == this) { return true; } } return false; } void observeEntity(RefEntity* ent) { if (!this->observingEntity(ent)) { this->register_observable(ent); } } /// virtual CubitStatus notify_observer( CubitObservable* watched, const CubitEvent& event, CubitBoolean fromObservable) { cout << "Notification: watched " << watched << " event " << event.get_event_type() << "," << event.get_event_sub_type() << " from " << (fromObservable ? "observable" : "something else") << "\n"; RefFace* face = dynamic_cast(watched); if (face) { cout << " " << face << " is a face\n"; } RefEdge* edge = dynamic_cast(watched); if (edge) { cout << " " << edge << " is an edge\n"; } if (event.get_event_type() == GEOMETRY_TOPOLOGY_MODIFIED) { cout << " Event: geom+topology modified (e.g., partitioned).\n"; } return CUBIT_SUCCESS; } }; int Persistence() { GeometryQueryEngine* engine = GeometryQueryTool::instance()->get_gqe(); if(!engine) { printf("no engine\n"); return 1; } DLIList faces; GeometryQueryTool::instance()->ref_faces(faces); GMem gmem; StupidObserver* observer = new StupidObserver; if (faces.size() > 0) { // Observe the first face. // It is firmly to one side of z=40 observer->observeEntity(faces[0]); } if (faces.size() > 26) { // Observe the 27th face. observer->observeEntity(faces[26]); } if (faces.size() > 149) { // Observe the 149th face. observer->observeEntity(faces[149]); } faces.clean_out(); // Cut the thing in twain: GeometryModifyTool* gmod = GeometryModifyTool::instance(); DLIList thingsToCut; DLIList thingsThatWereCut; DLIList cutNeighbors; GeometryQueryTool::instance()->bodies(thingsToCut); CubitVector basePoint(10., 0., 40.); CubitVector xyAxes[2]; xyAxes[0].set(1., 0., 0.); xyAxes[1].set(0., 1., 0.); double width = 100., height = 100.; cout << thingsToCut.size() << " things to cut\n"; gmod->webcut_with_planar_sheet( thingsToCut, basePoint, xyAxes, width, height, thingsThatWereCut, cutNeighbors, NO_IMPRINT, /*merge:*/ CUBIT_FALSE, /*preview:*/ CUBIT_FALSE); cout << thingsThatWereCut.size() << " things that were cut, " << cutNeighbors.size() << " cut neighbors" << "\n"; // get graphics data for the surfaces vtkNew pdata; vtkNew ppts; vtkNew surfs; vtkNew polys; surfs->SetName("SourceSurface"); pdata->SetPoints(ppts.GetPointer()); pdata->SetPolys(polys.GetPointer()); pdata->GetCellData()->SetPedigreeIds(surfs.GetPointer()); vtkIdType poff = 0; if (thingsThatWereCut.size() > 0) { for (int v = 0; v < thingsThatWereCut.size(); ++v, thingsThatWereCut.step()) { cout << "Volume " << (v + 1) << "/" << thingsThatWereCut.size() << "\n"; thingsThatWereCut.get()->ref_faces(faces); std::vector conn; for(int i=0; iget_surface_ptr(); if(!surf) { cout << "Skipping surfaceless face " << i << " of " << faces.size() << "\n"; continue; } if(engine->get_graphics(surf, &gmem) != CUBIT_SUCCESS || gmem.pointListCount == 0 || gmem.fListCount == 0) { printf("got no face facet data for face %i\n", face->id()); } else { const GPoint* pts = gmem.point_list(); const int* facets = gmem.facet_list(); int facet_size = gmem.fListCount; int plist_size = gmem.pointListCount; for (int j = 0; j < plist_size; ++j) { const GPoint& pt = pts[j]; ppts->InsertNextPoint(pt.x, pt.y, pt.z); } for(int j=0; jInsertNextCell(num, &conn[0]); surfs->InsertNextValue(i); } } poff = ppts->GetNumberOfPoints(); } cout << "\n"; } } vtkNew wri; wri->SetFileName("brep.vtp"); wri->SetInputDataObject(pdata.GetPointer()); wri->Write(); return 0; } // main program - initialize, then send to proper function int main (int argc, char **argv) { CubitStatus s = InitCGMA::initialize_cgma( ENGINE ); if (CUBIT_SUCCESS != s) return 1; //Do tests. ModelImportOptions opts; GeometryQueryTool::instance()->import_solid_model( argc > 1 ? argv[1] : "62_shaver1.brep", argc > 2 ? Model_File_Type(atoi(argv[2])) : OCC_TYPE, opts); int rsl = Persistence(); if (rsl == 1) { PRINT_INFO("Operation Failed"); } int ret_val = ( CubitMessage::instance()->error_count() ); if ( ret_val != 0 ) { PRINT_ERROR("Errors found during session.\n"); } else { ret_val = 0; } return ret_val; }