#include /*I "petscdmplex.h" I*/ #ifdef PETSC_HAVE_EGADS #include #endif /* We need to understand how to natively parse STEP files. There seems to be only one open source implementation of the STEP parser contained in the OpenCASCADE package. It is enough to make a strong man weep: https://github.com/tpaviot/oce/tree/master/src/STEPControl The STEP, and inner EXPRESS, formats are ISO standards, so they are documented https://stackoverflow.com/questions/26774037/documentation-or-specification-for-step-and-stp-files http://stepmod.sourceforge.net/express_model_spec/ but again it seems that there has been a deliberate effort at obfuscation, probably to raise the bar for entrants. */ /*@ DMPlexSnapToGeomModel - Given a coordinate point 'mcoords' on the mesh point 'p', return the closest coordinate point 'gcoords' on the geometry model associated with that point. Not collective Input Parameters: + dm - The DMPlex object . p - The mesh point - mcoords - A coordinate point lying on the mesh point Output Parameter: . gcoords - The closest coordinate point on the geometry model associated with 'p' to the given point Note: Returns the original coordinates if no geometry model is found. Right now the only supported geometry model is EGADS. Level: intermediate .seealso: DMRefine(), DMPlexCreate(), DMPlexSetRefinementUniform() @*/ PetscErrorCode DMPlexSnapToGeomModel(DM dm, PetscInt p, const PetscScalar mcoords[], PetscScalar gcoords[]) { #ifdef PETSC_HAVE_EGADS DMLabel bodyLabel, faceLabel, edgeLabel; PetscContainer modelObj; PetscInt bodyID, faceID, edgeID; ego *bodies; ego model, geom, body, face, edge; double point[3], params[3], result[3]; int Nb, oclass, mtype, *senses; #endif PetscInt cdim, d; PetscErrorCode ierr; PetscFunctionBegin; ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr); #ifdef PETSC_HAVE_EGADS ierr = DMGetLabel(dm, "EGADS Body ID", &bodyLabel);CHKERRQ(ierr); ierr = DMGetLabel(dm, "EGADS Face ID", &faceLabel);CHKERRQ(ierr); ierr = DMGetLabel(dm, "EGADS Edge ID", &edgeLabel);CHKERRQ(ierr); if (!bodyLabel || !faceLabel || !edgeLabel) { for (d = 0; d < cdim; ++d) gcoords[d] = mcoords[d]; PetscFunctionReturn(0); } ierr = DMLabelGetValue(bodyLabel, p, &bodyID);CHKERRQ(ierr); ierr = DMLabelGetValue(faceLabel, p, &faceID);CHKERRQ(ierr); ierr = DMLabelGetValue(edgeLabel, p, &edgeID);CHKERRQ(ierr); ierr = PetscObjectQuery((PetscObject) dm, "EGADS Model", (PetscObject *) &modelObj);CHKERRQ(ierr); ierr = PetscContainerGetPointer(modelObj, (void **) &model);CHKERRQ(ierr); ierr = EG_getTopology(model, &geom, &oclass, &mtype, NULL, &Nb, &bodies, &senses);CHKERRQ(ierr); if (bodyID >= Nb) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Body %D is not in [0, %d)", bodyID, Nb); body = bodies[bodyID]; for (d = 0; d < cdim; ++d) point[d] = mcoords[d]; if (edgeID >= 0) { ierr = EG_objectBodyTopo(body, EDGE, edgeID, &edge);CHKERRQ(ierr); ierr = EG_invEvaluate(edge, point, params, result); } else { ierr = EG_objectBodyTopo(body, FACE, faceID, &face);CHKERRQ(ierr); ierr = EG_invEvaluate(face, point, params, result); } for (d = 0; d < cdim; ++d) gcoords[d] = result[d]; #else for (d = 0; d < cdim; ++d) gcoords[d] = mcoords[d]; #endif PetscFunctionReturn(0); }