From 0461899071eb2718848f67bdb4419108a5ebdca2 Mon Sep 17 00:00:00 2001 From: Philippose Rajan Date: Fri, 19 Jun 2009 05:41:22 +0000 Subject: [PATCH] * Improved colour based boundary condition assignment for OCC geometry * Now allows the boundary condition numbers to be assigned via a profile file "netgen.ocf" * The old algorithm for automated selection is used if no profile file exists --- libsrc/occ/occauxfunctions.cpp | 168 ++++++++++++++++++++++++++++++++- libsrc/occ/occauxfunctions.hpp | 2 +- ng/Makefile.am | 2 +- ng/netgen.ocf | 9 ++ ng/ngpkg.cpp | 30 +++++- windows/postBuild_netgen.bat | 1 + 6 files changed, 208 insertions(+), 4 deletions(-) create mode 100644 ng/netgen.ocf diff --git a/libsrc/occ/occauxfunctions.cpp b/libsrc/occ/occauxfunctions.cpp index 0eb52670..f1eadb05 100644 --- a/libsrc/occ/occauxfunctions.cpp +++ b/libsrc/occ/occauxfunctions.cpp @@ -7,7 +7,144 @@ namespace netgen { - void OCCAutoColourBcProps(Mesh & mesh, OCCGeometry & occgeometry) + void OCCAutoColourAlg_UserProfile(Mesh & mesh, OCCGeometry & occgeometry, ifstream & ocf) + { + int numentries = 0; + + ocf >> numentries; + if(numentries > 0) + { + if(!ocf.good()) + { + throw NgException("OCCAutoColourAlg_UserProfile: Invalid or empty Boundary Colour Profile file\n"); + return; + } + + PrintMessage(3, "Number of colour entries: ", numentries); + } + else + { + PrintMessage(3, "OCCAutoColourAlg_UserProfile: No Boundary Colour entries found.... no changes made!"); + ocf.close(); + return; + } + + Array bc_colours(numentries); + Array bc_num(numentries); + + for(int i = 1; i <= numentries; i++) + { + int bcnum; + double col_red, col_green, col_blue; + + ocf >> bcnum; + if(bcnum < 1) bcnum = 1; + + bc_num.Elem(i) = bcnum; + ocf >> bc_colours.Elem(i).X() + >> bc_colours.Elem(i).Y() + >> bc_colours.Elem(i).Z(); + + if(!ocf.good()) + throw NgException("Boundary Colour file error: Number of entries do not match specified list size!!\n"); + + if(bc_colours.Elem(bcnum).X() < 0.0) bc_colours.Elem(bcnum).X() = 0.0; + if(bc_colours.Elem(bcnum).X() > 1.0) bc_colours.Elem(bcnum).X() = 1.0; + if(bc_colours.Elem(bcnum).Y() < 0.0) bc_colours.Elem(bcnum).X() = 0.0; + if(bc_colours.Elem(bcnum).Y() > 1.0) bc_colours.Elem(bcnum).X() = 1.0; + if(bc_colours.Elem(bcnum).Z() < 0.0) bc_colours.Elem(bcnum).X() = 0.0; + if(bc_colours.Elem(bcnum).Z() > 1.0) bc_colours.Elem(bcnum).X() = 1.0; + } + + PrintMessage(3, "Successfully loaded Boundary Colour Profile file...."); + ocf.close(); + + // Find the highest boundary condition number in the list + // All colours in the geometry which are not specified in the + // list will be given boundary condition numbers higher than this + // number + int max_bcnum = 0; + for(int i = 1; i <= bc_num.Size();i++) + { + if(bc_num.Elem(i) > max_bcnum) max_bcnum = bc_num.Elem(i); + } + + PrintMessage(3, "Highest boundary number in list = ",max_bcnum); + + TDF_LabelSequence all_colours; + + // Extract all the colours to see how many there are + occgeometry.face_colours->GetColors(all_colours); + PrintMessage(3,"\nNumber of colours defined in OCC Mesh: ", all_colours.Length()); + + if(all_colours.Length() == 0) + { + PrintMessage(3,"No colour data detected in OCC Mesh... no changes made!"); + return; + } + + int nfd = mesh.GetNFD(); + + for(int face_index = 1; face_index <= nfd; face_index++) + { + // Note: From the logic in file "occgenmesh.cpp", function "FindEdges" + // the Face Descriptor Number of an OCC face has a one-to-one mapping + // to the face number in the OCC face map (fmap) + TopoDS_Face face = TopoDS::Face(occgeometry.fmap(face_index)); + Quantity_Color face_colour; + + if(occgeometry.face_colours->GetColor(face,XCAFDoc_ColorSurf,face_colour)) + { + // Boolean variable to check if the boundary condition was applied + // or not... not applied would imply that the colour of the face + // does not exist in the list of colours in the profile file + bool bc_assigned = false; + + for(int col_index = 1; col_index <= bc_colours.Size(); col_index++) + { + Quantity_Color bc_colour; + + double col_red = bc_colours.Elem(col_index).X(); + double col_green = bc_colours.Elem(col_index).Y(); + double col_blue = bc_colours.Elem(col_index).Z(); + + bc_colour.SetValues(col_red,col_green,col_blue,Quantity_TOC_RGB); + + if((face_colour == bc_colour) && (!bc_assigned)) + { + mesh.GetFaceDescriptor(face_index).SetBCProperty(bc_num.Elem(col_index)); + bc_assigned = true; + break; + } + } + + // If the colour was not found in the list, add it to the list, and assign + // the next free boundary condition number to it + if(!bc_assigned) + { + double col_red = face_colour.Red(); + double col_green = face_colour.Green(); + double col_blue = face_colour.Blue(); + + Vec3d new_colour(col_red,col_green,col_blue); + + max_bcnum++; + bc_num.Append(max_bcnum); + bc_colours.Append(new_colour); + + mesh.GetFaceDescriptor(face_index).SetBCProperty(max_bcnum); + } + } + else + { + mesh.GetFaceDescriptor(face_index).SetBCProperty(0); + } + } + } + + + + void OCCAutoColourAlg_Sorted(Mesh & mesh, OCCGeometry & occgeometry) { TDF_LabelSequence all_colours; Array faces_sorted; @@ -134,5 +271,34 @@ namespace netgen ,ref_colour.Blue(),")","\n"); } } + + + + void OCCAutoColourBcProps(Mesh & mesh, OCCGeometry & occgeometry, const char * occcolourfile) + { + // Go directly to the alternate algorithm if no colour profile file was specified + if(!occcolourfile) + { + OCCAutoColourAlg_Sorted(mesh,occgeometry); + } + + ifstream ocf(occcolourfile); + + // If there was an error opening the Colour profile file, jump to the alternate + // algorithm after printing a message + if(!ocf) + { + PrintMessage(1,"OCCAutoColourBcProps: Error loading Boundary Colour Profile file ", + occcolourfile, " ....","Switching to alternate algorithm!"); + + OCCAutoColourAlg_Sorted(mesh,occgeometry); + } + // If the file opens successfully, call the function which assigns boundary conditions + // based on the colour profile file + else + { + OCCAutoColourAlg_UserProfile(mesh,occgeometry,ocf); + } + } } #endif // #ifdef OCCGEOMETRY diff --git a/libsrc/occ/occauxfunctions.hpp b/libsrc/occ/occauxfunctions.hpp index f64feb36..828dff6a 100644 --- a/libsrc/occ/occauxfunctions.hpp +++ b/libsrc/occ/occauxfunctions.hpp @@ -39,7 +39,7 @@ namespace netgen - BC Prop 2: 2200 : Colour 2 - BC Prop 3: 8500 : Colour 0 (no colour defined) */ - extern void OCCAutoColourBcProps(Mesh & mesh, OCCGeometry & occgeometry); + extern void OCCAutoColourBcProps(Mesh & mesh, OCCGeometry & occgeometry, const char *occcolourfile); } #endif diff --git a/ng/Makefile.am b/ng/Makefile.am index 63038a6a..ff95f41b 100644 --- a/ng/Makefile.am +++ b/ng/Makefile.am @@ -27,7 +27,7 @@ netgen_LDADD = $(top_builddir)/libsrc/visualization/libvisual.a \ dist_bin_SCRIPTS = dialog.tcl menustat.tcl ngicon.tcl ng.tcl \ ngvisual.tcl sockets.tcl drawing.tcl nghelp.tcl ngshell.tcl \ -ngtesting.tcl parameters.tcl variables.tcl +ngtesting.tcl parameters.tcl variables.tcl netgen.ocf # netgen_LDFLAGS = -pg -static netgen_LDFLAGS = -rdynamic -pg -static diff --git a/ng/netgen.ocf b/ng/netgen.ocf new file mode 100644 index 00000000..acffff84 --- /dev/null +++ b/ng/netgen.ocf @@ -0,0 +1,9 @@ +8 +1 0.0000 0.0000 0.0000 +2 1.0000 0.0000 0.0000 +3 0.0000 1.0000 0.0000 +4 0.0000 0.0000 1.0000 +5 1.0000 1.0000 0.0000 +6 0.0000 1.0000 1.0000 +7 1.0000 0.0000 1.0000 +8 1.0000 1.0000 1.0000 diff --git a/ng/ngpkg.cpp b/ng/ngpkg.cpp index 1021f41d..07932b43 100644 --- a/ng/ngpkg.cpp +++ b/ng/ngpkg.cpp @@ -1590,7 +1590,7 @@ namespace netgen return TCL_ERROR; } - OCCAutoColourBcProps(*mesh, *occgeometry); + OCCAutoColourBcProps(*mesh, *occgeometry, "netgen.ocf"); return TCL_OK; #else @@ -1961,6 +1961,30 @@ namespace netgen } + // Philippose Rajan - 13 June 2009 + // Added a new TCL function call for the generation + // of prismatic boundary layers + int Ng_GenerateBoundaryLayer (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + + if(multithread.running) + { + Tcl_SetResult(interp, err_jobrunning, TCL_STATIC); + return TCL_ERROR; + } + + GenerateBoundaryLayer (*mesh); + return TCL_OK; + } + + int Ng_InsertVirtualBL (ClientData clientData, Tcl_Interp * interp, int argc, tcl_const char *argv[]) @@ -5064,6 +5088,10 @@ namespace netgen (ClientData)NULL, (Tcl_CmdDeleteProc*) NULL); + Tcl_CreateCommand (interp, "Ng_GenerateBoundaryLayer", Ng_GenerateBoundaryLayer, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + Tcl_CreateCommand (interp, "Ng_InsertVirtualBL", Ng_InsertVirtualBL, (ClientData)NULL, (Tcl_CmdDeleteProc*) NULL); diff --git a/windows/postBuild_netgen.bat b/windows/postBuild_netgen.bat index 35bee232..b74988d5 100644 --- a/windows/postBuild_netgen.bat +++ b/windows/postBuild_netgen.bat @@ -43,6 +43,7 @@ echo Embedding Manifest into the executable: Completed OK!! REM *** Copy the core TCL files into the Install Folder *** echo Installing core TCL files into %INSTALL_FOLDER%\bin .... xcopy "%NETGEN_TCLSRC%\*.tcl" "%INSTALL_FOLDER%\bin\" /i /d /y +xcopy "%NETGEN_TCLSRC%\*.ocf" "%INSTALL_FOLDER%\bin\" /i /d /y if errorlevel 1 goto CoreTCLFailed echo Installing core TCL Files: Completed OK!!