void Meshing2 :: BlockFillLocalH (Mesh & mesh, const MeshingParameters & mp)
  {
    double filldist = mp.filldist;

    cout << "blockfill local h" << endl;
    cout << "rel filldist = " << filldist << endl;
    PrintMessage (3, "blockfill local h");

    Array<Point<3> > npoints;

    // adfront -> CreateTrees();

    Box<3> bbox ( Box<3>::EMPTY_BOX );
    double maxh = 0;

    for (int i = 0; i < adfront->GetNFL(); i++)
      {
	const FrontLine & line = adfront->GetLine (i);

	const Point<3> & p1 = adfront->GetPoint(line.L().I1());
	const Point<3> & p2 = adfront->GetPoint(line.L().I2());

	double hi = Dist (p1, p2);
	if (hi > maxh) maxh = hi;

	bbox.Add (p1);
	bbox.Add (p2);
      }


    cout << "bbox = " << bbox << endl;


    // Point<3> mpc = bbox.Center();
    bbox.Increase (bbox.Diam()/2);
    Box<3> meshbox = bbox;

    LocalH loch2 (bbox, 1);

    if (mp.maxh < maxh) maxh = mp.maxh;

    bool changed;
    do
      {
	mesh.LocalHFunction().ClearFlags();

	for (int i = 0; i < adfront->GetNFL(); i++)
	  {
	    const FrontLine & line = adfront->GetLine(i);

	    Box<3> bbox (adfront->GetPoint (line.L().I1()));
	    bbox.Add (adfront->GetPoint (line.L().I2()));


	    double filld = filldist * bbox.Diam();
	    bbox.Increase (filld);

	    mesh.LocalHFunction().CutBoundary (bbox);
	  }


	mesh.LocalHFunction().FindInnerBoxes (adfront, NULL);

	npoints.SetSize(0);
	mesh.LocalHFunction().GetInnerPoints (npoints);

	changed = false;
	for (int i = 0; i < npoints.Size(); i++)
	  {
	    if (mesh.LocalHFunction().GetH(npoints[i]) > 1.5 * maxh)
	      {
		mesh.LocalHFunction().SetH (npoints[i], maxh);
		changed = true;
	      }
	  }
      }
    while (changed);

    if (debugparam.slowchecks)
      (*testout) << "Blockfill with points: " << endl;
    *testout << "loch = " << mesh.LocalHFunction() << endl;

    *testout << "npoints = " << endl << npoints << endl;

    for (int i = 1; i <= npoints.Size(); i++)
      {
	if (meshbox.IsIn (npoints.Get(i)))
	  {
	    PointIndex gpnum = mesh.AddPoint (npoints.Get(i));
	    adfront->AddPoint (npoints.Get(i), gpnum);

	    if (debugparam.slowchecks)
	      {
		(*testout) << npoints.Get(i) << endl;

		Point<2> p2d (npoints.Get(i)(0), npoints.Get(i)(1));
		if (!adfront->Inside(p2d))
		  {
		    cout << "add outside point" << endl;
		    (*testout) << "outside" << endl;
		  }
	      }

	  }
      }



  // find outer points

    loch2.ClearFlags();

    for (int i = 0; i < adfront->GetNFL(); i++)
      {
	const FrontLine & line = adfront->GetLine(i);

	Box<3> bbox (adfront->GetPoint (line.L().I1()));
	bbox.Add (adfront->GetPoint (line.L().I2()));

	loch2.SetH (bbox.Center(), bbox.Diam());
      }


    for (int i = 0; i < adfront->GetNFL(); i++)
      {
	const FrontLine & line = adfront->GetLine(i);

	Box<3> bbox (adfront->GetPoint (line.L().I1()));
	bbox.Add (adfront->GetPoint (line.L().I2()));

	bbox.Increase (filldist * bbox.Diam());
	loch2.CutBoundary (bbox);
      }

    loch2.FindInnerBoxes (adfront, NULL);

    npoints.SetSize(0);
    loch2.GetOuterPoints (npoints);

    for (int i = 1; i <= npoints.Size(); i++)
      {
	if (meshbox.IsIn (npoints.Get(i)))
	  {
	    PointIndex gpnum = mesh.AddPoint (npoints.Get(i));
	    adfront->AddPoint (npoints.Get(i), gpnum);
	  }
      }

  }
Beispiel #2
0
  void VisualSceneGeometry :: BuildScene (int zoomall)
  {
    VisualScene::BuildScene(zoomall); // setting light ...
    Box<3> box;
    int hasp = 0;
    for (int i = 0; i < geometry->GetNTopLevelObjects(); i++)
      {
	const TriangleApproximation & ta =
	  *geometry->GetTriApprox(i);
	if (!&ta) continue;

	for (int j = 0; j < ta.GetNP(); j++)      
	  {
	    if (hasp)
	      box.Add (ta.GetPoint(j));
	    else
	      {
		hasp = 1;
		box.Set (ta.GetPoint(j));
	      }
	  }
      }
    if (hasp)
      {
	center = box.Center();
	rad = box.Diam() / 2;
      }
    else
      {
	center = Point3d(0,0,0);
	rad = 1;
      }

    CalcTransformationMatrices();

    for (int i = 0; i < trilists.Size(); i++)
      glDeleteLists (trilists[i], 1);
    trilists.SetSize(0);

    for (int i = 0; i < geometry->GetNTopLevelObjects(); i++)
      {
	trilists.Append (glGenLists (1));
	glNewList (trilists.Last(), GL_COMPILE); 
	glEnable (GL_NORMALIZE);
	const TriangleApproximation & ta =
	  *geometry->GetTriApprox(i);
	if (&ta) 
	  {
	    glEnableClientState(GL_VERTEX_ARRAY);
	    glVertexPointer(3, GL_DOUBLE, 0, &ta.GetPoint(0)(0));

	    glEnableClientState(GL_NORMAL_ARRAY);
	    glNormalPointer(GL_DOUBLE, 0, &ta.GetNormal(0)(0));
	    
	    for (int j = 0; j < ta.GetNT(); j++)
	      glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, & (ta.GetTriangle(j)[0]));

	    glDisableClientState(GL_VERTEX_ARRAY);
	    glDisableClientState(GL_NORMAL_ARRAY);
            /*
	    for (int j = 0; j < ta.GetNT(); j++)
	      {
		glBegin (GL_TRIANGLES);
		for (int k = 0; k < 3; k++)
		  {
		    int pi = ta.GetTriangle(j)[k];
		    glNormal3dv (ta.GetNormal(pi));
		    glVertex3dv (ta.GetPoint(pi));
                    cout << "v = " << ta.GetPoint(pi) << endl;
		  }
		glEnd ();
	      }
            */
	  }
	glEndList ();
      }
  }
bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh&         aMesh,
        const TopoDS_Shape& aShape)
{
    netgen::multithread.terminate = 0;
    //netgen::multithread.task = "Surface meshing";

    SMESHDS_Mesh* meshDS = aMesh.GetMeshDS();
    SMESH_MesherHelper helper(aMesh);
    helper.SetElementsOnShape( true );

    NETGENPlugin_NetgenLibWrapper ngLib;
    ngLib._isComputeOk = false;

    netgen::Mesh   ngMeshNoLocSize;
#if NETGEN_VERSION < 6
    netgen::Mesh * ngMeshes[2] = { (netgen::Mesh*) ngLib._ngMesh,  & ngMeshNoLocSize };
#else
    netgen::Mesh * ngMeshes[2] = { (netgen::Mesh*) ngLib._ngMesh.get(),  & ngMeshNoLocSize };
#endif
    netgen::OCCGeometry occgeoComm;

    // min / max sizes are set as follows:
    // if ( _hypParameters )
    //    min and max are defined by the user
    // else if ( _hypLengthFromEdges )
    //    min = aMesher.GetDefaultMinSize()
    //    max = average segment len of a FACE
    // else if ( _hypMaxElementArea )
    //    min = aMesher.GetDefaultMinSize()
    //    max = f( _hypMaxElementArea )
    // else
    //    min = aMesher.GetDefaultMinSize()
    //    max = max segment len of a FACE

    NETGENPlugin_Mesher aMesher( &aMesh, aShape, /*isVolume=*/false);
    aMesher.SetParameters( _hypParameters ); // _hypParameters -> netgen::mparam
    const bool toOptimize = _hypParameters ? _hypParameters->GetOptimize() : true;
    if ( _hypMaxElementArea )
    {
        netgen::mparam.maxh = sqrt( 2. * _hypMaxElementArea->GetMaxArea() / sqrt(3.0) );
    }
    if ( _hypQuadranglePreference )
        netgen::mparam.quad = true;

    // local size is common for all FACEs in aShape?
    const bool isCommonLocalSize = ( !_hypLengthFromEdges && !_hypMaxElementArea && netgen::mparam.uselocalh );
    const bool isDefaultHyp = ( !_hypLengthFromEdges && !_hypMaxElementArea && !_hypParameters );

    if ( isCommonLocalSize ) // compute common local size in ngMeshes[0]
    {
        //list< SMESH_subMesh* > meshedSM[4]; --> all sub-shapes are added to occgeoComm
        aMesher.PrepareOCCgeometry( occgeoComm, aShape, aMesh );//, meshedSM );

        // local size set at MESHCONST_ANALYSE step depends on
        // minh, face_maxh, grading and curvaturesafety; find minh if not set by the user
        if ( !_hypParameters || netgen::mparam.minh < DBL_MIN )
        {
            if ( !_hypParameters )
                netgen::mparam.maxh = occgeoComm.GetBoundingBox().Diam() / 3.;
            netgen::mparam.minh = aMesher.GetDefaultMinSize( aShape, netgen::mparam.maxh );
        }
        // set local size depending on curvature and NOT closeness of EDGEs
        netgen::occparam.resthcloseedgeenable = false;
        //netgen::occparam.resthcloseedgefac = 1.0 + netgen::mparam.grading;
        occgeoComm.face_maxh = netgen::mparam.maxh;
        netgen::OCCSetLocalMeshSize( occgeoComm, *ngMeshes[0] );
        occgeoComm.emap.Clear();
        occgeoComm.vmap.Clear();

        // set local size according to size of existing segments
        const double factor = netgen::occparam.resthcloseedgefac;
        TopTools_IndexedMapOfShape edgeMap;
        TopExp::MapShapes( aMesh.GetShapeToMesh(), TopAbs_EDGE, edgeMap );
        for ( int iE = 1; iE <= edgeMap.Extent(); ++iE )
        {
            const TopoDS_Shape& edge = edgeMap( iE );
            if ( SMESH_Algo::isDegenerated( TopoDS::Edge( edge ))/* ||
           helper.IsSubShape( edge, aShape )*/)
                continue;
            SMESHDS_SubMesh* smDS = meshDS->MeshElements( edge );
            if ( !smDS ) continue;
            SMDS_ElemIteratorPtr segIt = smDS->GetElements();
            while ( segIt->more() )
            {
                const SMDS_MeshElement* seg = segIt->next();
                SMESH_TNodeXYZ n1 = seg->GetNode(0);
                SMESH_TNodeXYZ n2 = seg->GetNode(1);
                gp_XYZ p = 0.5 * ( n1 + n2 );
                netgen::Point3d pi(p.X(), p.Y(), p.Z());
                ngMeshes[0]->RestrictLocalH( pi, factor * ( n1 - n2 ).Modulus() );
            }
        }
    }
    netgen::mparam.uselocalh = toOptimize; // restore as it is used at surface optimization

    // ==================
    // Loop on all FACEs
    // ==================

    vector< const SMDS_MeshNode* > nodeVec;

    TopExp_Explorer fExp( aShape, TopAbs_FACE );
    for ( int iF = 0; fExp.More(); fExp.Next(), ++iF )
    {
        TopoDS_Face F = TopoDS::Face( fExp.Current() /*.Oriented( TopAbs_FORWARD )*/);
        int    faceID = meshDS->ShapeToIndex( F );
        SMESH_ComputeErrorPtr& faceErr = aMesh.GetSubMesh( F )->GetComputeError();

        _quadraticMesh = helper.IsQuadraticSubMesh( F );
        const bool ignoreMediumNodes = _quadraticMesh;

        // build viscous layers if required
        if ( F.Orientation() != TopAbs_FORWARD &&
                F.Orientation() != TopAbs_REVERSED )
            F.Orientation( TopAbs_FORWARD ); // avoid pb with TopAbs_INTERNAL
        SMESH_ProxyMesh::Ptr proxyMesh = StdMeshers_ViscousLayers2D::Compute( aMesh, F );
        if ( !proxyMesh )
            continue;

        // ------------------------
        // get all EDGEs of a FACE
        // ------------------------
        TSideVector wires =
            StdMeshers_FaceSide::GetFaceWires( F, aMesh, ignoreMediumNodes, faceErr, proxyMesh );
        if ( faceErr && !faceErr->IsOK() )
            continue;
        int nbWires = wires.size();
        if ( nbWires == 0 )
        {
            faceErr.reset
            ( new SMESH_ComputeError
              ( COMPERR_ALGO_FAILED, "Problem in StdMeshers_FaceSide::GetFaceWires()" ));
            continue;
        }
        if ( wires[0]->NbSegments() < 3 ) // ex: a circle with 2 segments
        {
            faceErr.reset
            ( new SMESH_ComputeError
              ( COMPERR_BAD_INPUT_MESH, SMESH_Comment("Too few segments: ")<<wires[0]->NbSegments()) );
            continue;
        }

        // ----------------------
        // compute maxh of a FACE
        // ----------------------

        if ( !_hypParameters )
        {
            double edgeLength = 0;
            if (_hypLengthFromEdges )
            {
                // compute edgeLength as an average segment length
                int nbSegments = 0;
                for ( int iW = 0; iW < nbWires; ++iW )
                {
                    edgeLength += wires[ iW ]->Length();
                    nbSegments += wires[ iW ]->NbSegments();
                }
                if ( nbSegments )
                    edgeLength /= nbSegments;
                netgen::mparam.maxh = edgeLength;
            }
            else if ( isDefaultHyp )
            {
                // set edgeLength by a longest segment
                double maxSeg2 = 0;
                for ( int iW = 0; iW < nbWires; ++iW )
                {
                    const UVPtStructVec& points = wires[ iW ]->GetUVPtStruct();
                    if ( points.empty() )
                        return error( COMPERR_BAD_INPUT_MESH );
                    gp_Pnt pPrev = SMESH_TNodeXYZ( points[0].node );
                    for ( size_t i = 1; i < points.size(); ++i )
                    {
                        gp_Pnt p = SMESH_TNodeXYZ( points[i].node );
                        maxSeg2 = Max( maxSeg2, p.SquareDistance( pPrev ));
                        pPrev = p;
                    }
                }
                edgeLength = sqrt( maxSeg2 ) * 1.05;
                netgen::mparam.maxh = edgeLength;
            }
            if ( netgen::mparam.maxh < DBL_MIN )
                netgen::mparam.maxh = occgeoComm.GetBoundingBox().Diam();

            if ( !isCommonLocalSize )
            {
                netgen::mparam.minh = aMesher.GetDefaultMinSize( F, netgen::mparam.maxh );
            }
        }

        // prepare occgeom
        netgen::OCCGeometry occgeom;
        occgeom.shape = F;
        occgeom.fmap.Add( F );
        occgeom.CalcBoundingBox();
        occgeom.facemeshstatus.SetSize(1);
        occgeom.facemeshstatus = 0;
        occgeom.face_maxh_modified.SetSize(1);
        occgeom.face_maxh_modified = 0;
        occgeom.face_maxh.SetSize(1);
        occgeom.face_maxh = netgen::mparam.maxh;

        // -------------------------
        // Fill netgen mesh
        // -------------------------

        // MESHCONST_ANALYSE step may lead to a failure, so we make an attempt
        // w/o MESHCONST_ANALYSE at the second loop
        int err = 0;
        enum { LOC_SIZE, NO_LOC_SIZE };
        int iLoop = isCommonLocalSize ? 0 : 1;
        for ( ; iLoop < 2; iLoop++ )
        {
            //bool isMESHCONST_ANALYSE = false;
            InitComputeError();

            netgen::Mesh * ngMesh = ngMeshes[ iLoop ];
            ngMesh->DeleteMesh();

            if ( iLoop == NO_LOC_SIZE )
            {
                ngMesh->SetGlobalH ( mparam.maxh );
                ngMesh->SetMinimalH( mparam.minh );
                Box<3> bb = occgeom.GetBoundingBox();
                bb.Increase (bb.Diam()/10);
                ngMesh->SetLocalH (bb.PMin(), bb.PMax(), mparam.grading);
            }

            nodeVec.clear();
            faceErr = aMesher.AddSegmentsToMesh( *ngMesh, occgeom, wires, helper, nodeVec,
                                                 /*overrideMinH=*/!_hypParameters);
            if ( faceErr && !faceErr->IsOK() )
                break;

            //if ( !isCommonLocalSize )
            //limitSize( ngMesh, mparam.maxh * 0.8);

            // -------------------------
            // Generate surface mesh
            // -------------------------

            const int startWith = MESHCONST_MESHSURFACE;
            const int endWith   = toOptimize ? MESHCONST_OPTSURFACE : MESHCONST_MESHSURFACE;

            SMESH_Comment str;
            try {
                OCC_CATCH_SIGNALS;

#if NETGEN_VERSION >=6
                std::shared_ptr<netgen::Mesh> mesh_ptr(ngMesh,  [](netgen::Mesh*) {});
                err = netgen::OCCGenerateMesh(occgeom, mesh_ptr, netgen::mparam, startWith, endWith);
#elif NETGEN_VERSION > 4
                err = netgen::OCCGenerateMesh(occgeom, ngMesh, netgen::mparam, startWith, endWith);
#else
                char *optstr = 0;
                err = netgen::OCCGenerateMesh(occgeom, ngMesh, startWith, endWith, optstr);
#endif
                if ( netgen::multithread.terminate )
                    return false;
                if ( err )
                    str << "Error in netgen::OCCGenerateMesh() at " << netgen::multithread.task;
            }
            catch (Standard_Failure& ex)
            {
                err = 1;
                str << "Exception in  netgen::OCCGenerateMesh()"
                    << " at " << netgen::multithread.task
                    << ": " << ex.DynamicType()->Name();
                if ( ex.GetMessageString() && strlen( ex.GetMessageString() ))
                    str << ": " << ex.GetMessageString();
            }
            catch (...) {
                err = 1;
                str << "Exception in  netgen::OCCGenerateMesh()"
                    << " at " << netgen::multithread.task;
            }
            if ( err )
            {
                if ( aMesher.FixFaceMesh( occgeom, *ngMesh, 1 ))
                    break;
                if ( iLoop == LOC_SIZE )
                {
                    netgen::mparam.minh = netgen::mparam.maxh;
                    netgen::mparam.maxh = 0;
                    for ( int iW = 0; iW < wires.size(); ++iW )
                    {
                        StdMeshers_FaceSidePtr wire = wires[ iW ];
                        const vector<UVPtStruct>& uvPtVec = wire->GetUVPtStruct();
                        for ( size_t iP = 1; iP < uvPtVec.size(); ++iP )
                        {
                            SMESH_TNodeXYZ   p( uvPtVec[ iP ].node );
                            netgen::Point3d np( p.X(),p.Y(),p.Z());
                            double segLen = p.Distance( uvPtVec[ iP-1 ].node );
                            double   size = ngMesh->GetH( np );
                            netgen::mparam.minh = Min( netgen::mparam.minh, size );
                            netgen::mparam.maxh = Max( netgen::mparam.maxh, segLen );
                        }
                    }
                    //cerr << "min " << netgen::mparam.minh << " max " << netgen::mparam.maxh << endl;
                    netgen::mparam.minh *= 0.9;
                    netgen::mparam.maxh *= 1.1;
                    continue;
                }
                else
                {
                    faceErr.reset( new SMESH_ComputeError( COMPERR_ALGO_FAILED, str ));
                }
            }


            // ----------------------------------------------------
            // Fill the SMESHDS with the generated nodes and faces
            // ----------------------------------------------------

            int nbNodes = ngMesh->GetNP();
            int nbFaces = ngMesh->GetNSE();

            int nbInputNodes = nodeVec.size()-1;
            nodeVec.resize( nbNodes+1, 0 );

            // add nodes
            for ( int ngID = nbInputNodes + 1; ngID <= nbNodes; ++ngID )
            {
                const MeshPoint& ngPoint = ngMesh->Point( ngID );
                SMDS_MeshNode * node = meshDS->AddNode(ngPoint(0), ngPoint(1), ngPoint(2));
                nodeVec[ ngID ] = node;
            }

            // create faces
            int i,j;
            vector<const SMDS_MeshNode*> nodes;
            for ( i = 1; i <= nbFaces ; ++i )
            {
                const Element2d& elem = ngMesh->SurfaceElement(i);
                nodes.resize( elem.GetNP() );
                for (j=1; j <= elem.GetNP(); ++j)
                {
                    int pind = elem.PNum(j);
                    if ( pind < 1 )
                        break;
                    nodes[ j-1 ] = nodeVec[ pind ];
                    if ( nodes[ j-1 ]->GetPosition()->GetTypeOfPosition() == SMDS_TOP_3DSPACE )
                    {
                        const PointGeomInfo& pgi = elem.GeomInfoPi(j);
                        meshDS->SetNodeOnFace( nodes[ j-1 ], faceID, pgi.u, pgi.v);
                    }
                }
                if ( j > elem.GetNP() )
                {
                    SMDS_MeshFace* face = 0;
                    if ( elem.GetType() == TRIG )
                        face = helper.AddFace(nodes[0],nodes[1],nodes[2]);
                    else
                        face = helper.AddFace(nodes[0],nodes[1],nodes[2],nodes[3]);
                }
            }

            break;
        } // two attempts
    } // loop on FACEs

    return true;
}
Beispiel #4
0
  void MeshFromSpline2D (SplineGeometry2d & geometry,
			 Mesh *& mesh, 
			 MeshingParameters & mp)
  {
    PrintMessage (1, "Generate Mesh from spline geometry");

    double h = mp.maxh;

    Box<2> bbox = geometry.GetBoundingBox ();

    if (bbox.Diam() < h) 
      {
	h = bbox.Diam();
	mp.maxh = h;
      }

    mesh = new Mesh;
    mesh->SetDimension (2);

    geometry.PartitionBoundary (h, *mesh);

    // marks mesh points for hp-refinement
    for (int i = 0; i < geometry.GetNP(); i++)
      if (geometry.GetPoint(i).hpref)
	{
	  double mindist = 1e99;
	  PointIndex mpi(0);
	  Point<2> gp = geometry.GetPoint(i);
	  Point<3> gp3(gp(0), gp(1), 0);
	  for (PointIndex pi = PointIndex::BASE; 
	       pi < mesh->GetNP()+PointIndex::BASE; pi++)
	    if (Dist2(gp3, (*mesh)[pi]) < mindist)
	      {
		mpi = pi;
		mindist = Dist2(gp3, (*mesh)[pi]);
	      }
	  (*mesh)[mpi].Singularity(1.);
	}


    int maxdomnr = 0;
    for (SegmentIndex si = 0; si < mesh->GetNSeg(); si++)
      {
	if ( (*mesh)[si].domin > maxdomnr) maxdomnr = (*mesh)[si].domin;
	if ( (*mesh)[si].domout > maxdomnr) maxdomnr = (*mesh)[si].domout;
      }

    mesh->ClearFaceDescriptors();
    for (int i = 1; i <= maxdomnr; i++)
      mesh->AddFaceDescriptor (FaceDescriptor (i, 0, 0, i));

    // set Array<string*> bcnames... 
    // number of bcnames
    int maxsegmentindex = 0;
    for (SegmentIndex si = 0; si < mesh->GetNSeg(); si++)
      {
	if ( (*mesh)[si].si > maxsegmentindex) maxsegmentindex = (*mesh)[si].si;
      }

    mesh->SetNBCNames(maxsegmentindex);

    for ( int sindex = 0; sindex < maxsegmentindex; sindex++ )
      mesh->SetBCName ( sindex, geometry.GetBCName( sindex+1 ) );

    for (SegmentIndex si = 0; si < mesh->GetNSeg(); si++)
      (*mesh)[si].SetBCName ( (*mesh).GetBCNamePtr( (*mesh)[si].si-1 ) );

    Point3d pmin(bbox.PMin()(0), bbox.PMin()(1), -bbox.Diam());
    Point3d pmax(bbox.PMax()(0), bbox.PMax()(1), bbox.Diam());

    mesh->SetLocalH (pmin, pmax, mparam.grading);
    mesh->SetGlobalH (h);
  
    mesh->CalcLocalH();

    int bnp = mesh->GetNP(); // boundary points

    int hquad = mparam.quad;


    for (int domnr = 1; domnr <= maxdomnr; domnr++)
      if (geometry.GetDomainTensorMeshing (domnr))
        { // tensor product mesh
          
          Array<PointIndex, PointIndex::BASE> nextpi(bnp);
          Array<int, PointIndex::BASE> si1(bnp), si2(bnp);
          PointIndex firstpi;
          
          nextpi = -1;
          si1 = -1;
          si2 = -1;
          for (SegmentIndex si = 0; si < mesh->GetNSeg(); si++)
            {
              int p1 = -1, p2 = -2;

              if ( (*mesh)[si].domin == domnr)
                { p1 = (*mesh)[si][0]; p2 = (*mesh)[si][1]; }
              if ( (*mesh)[si].domout == domnr)
                { p1 = (*mesh)[si][1]; p2 = (*mesh)[si][0]; }
              
              if (p1 == -1) continue;

              nextpi[p1] = p2;       // counter-clockwise
              
              int index = (*mesh)[si].si;
              if (si1[p1] != index && si2[p1] != index)
                { si2[p1] = si1[p1]; si1[p1] = index; }
              if (si1[p2] != index && si2[p2] != index)
                { si2[p2] = si1[p2]; si1[p2] = index; }
            }

          PointIndex c1(0), c2, c3, c4;  // 4 corner points
          int nex = 1, ney = 1;

          for (PointIndex pi = 1; pi <= si2.Size(); pi++)
            if (si2[pi] != -1)
              { c1 = pi; break; }      

          for (c2 = nextpi[c1]; si2[c2] == -1; c2 = nextpi[c2], nex++);
          for (c3 = nextpi[c2]; si2[c3] == -1; c3 = nextpi[c3], ney++);
          for (c4 = nextpi[c3]; si2[c4] == -1; c4 = nextpi[c4]);



          Array<PointIndex> pts ( (nex+1) * (ney+1) );   // x ... inner loop
          pts = -1;

          for (PointIndex pi = c1, i = 0; pi != c2; pi = nextpi[pi], i++)
            pts[i] = pi;
          for (PointIndex pi = c2, i = 0; pi != c3; pi = nextpi[pi], i++)
            pts[(nex+1)*i+nex] = pi;
          for (PointIndex pi = c3, i = 0; pi != c4; pi = nextpi[pi], i++)
            pts[(nex+1)*(ney+1)-i-1] = pi;
          for (PointIndex pi = c4, i = 0; pi != c1; pi = nextpi[pi], i++)
            pts[(nex+1)*(ney-i)] = pi;


          for (PointIndex pix = nextpi[c1], ix = 0; pix != c2; pix = nextpi[pix], ix++)
            for (PointIndex piy = nextpi[c2], iy = 0; piy != c3; piy = nextpi[piy], iy++)
              {
                Point<3> p = (*mesh)[pix] + ( (*mesh)[piy] - (*mesh)[c2] );
                pts[(nex+1)*(iy+1) + ix+1] = mesh -> AddPoint (p , 1, FIXEDPOINT);
              }

          for (int i = 0; i < ney; i++)
            for (int j = 0; j < nex; j++)
              {
                Element2d el(QUAD);
                el[0] = pts[i*(nex+1)+j];
                el[1] = pts[i*(nex+1)+j+1];
                el[2] = pts[(i+1)*(nex+1)+j+1];
                el[3] = pts[(i+1)*(nex+1)+j];
                el.SetIndex (domnr);

                mesh -> AddSurfaceElement (el);
              }
        }




    for (int domnr = 1; domnr <= maxdomnr; domnr++)
      {
        if (geometry.GetDomainTensorMeshing (domnr)) continue;

	if ( geometry.GetDomainMaxh ( domnr ) > 0 )
	  h = geometry.GetDomainMaxh(domnr);


	PrintMessage (3, "Meshing domain ", domnr, " / ", maxdomnr);

	int oldnf = mesh->GetNSE();

        mparam.quad = hquad || geometry.GetDomainQuadMeshing (domnr);

	Meshing2 meshing (Box<3> (pmin, pmax));

	for (PointIndex pi = PointIndex::BASE; pi < bnp+PointIndex::BASE; pi++)
	  meshing.AddPoint ( (*mesh)[pi], pi);
      

	PointGeomInfo gi;
	gi.trignum = 1;
	for (SegmentIndex si = 0; si < mesh->GetNSeg(); si++)
	  {
	    if ( (*mesh)[si].domin == domnr)
	      meshing.AddBoundaryElement ( (*mesh)[si][0] + 1 - PointIndex::BASE, 
					   (*mesh)[si][1] + 1 - PointIndex::BASE, gi, gi);
	    if ( (*mesh)[si].domout == domnr)
	      meshing.AddBoundaryElement ( (*mesh)[si][1] + 1 - PointIndex::BASE, 
					   (*mesh)[si][0] + 1 - PointIndex::BASE, gi, gi);
	  }


	mparam.checkoverlap = 0;

	meshing.GenerateMesh (*mesh, h, domnr);

	for (SurfaceElementIndex sei = oldnf; sei < mesh->GetNSE(); sei++)
	  (*mesh)[sei].SetIndex (domnr);


	// astrid
	char * material;
	geometry.GetMaterial( domnr, material );
	if ( material )
	  {
	    (*mesh).SetMaterial ( domnr,  material );
	  }

      }

    mparam.quad = hquad;



    int hsteps = mp.optsteps2d;

    mp.optimize2d = "smcm"; 
    mp.optsteps2d = hsteps/2;
    Optimize2d (*mesh, mp);

    mp.optimize2d = "Smcm"; 
    mp.optsteps2d = (hsteps+1)/2;
    Optimize2d (*mesh, mp);

    mp.optsteps2d = hsteps;

    mesh->Compress();
    mesh -> SetNextMajorTimeStamp();


    extern void Render();
    Render();
  }
Beispiel #5
0
/*
double stlgh;
double GetH(const Point3d& p, double x)
{
  return stlgh;//+0.5)*(x+0.5);
}
*/
STLLine* STLLine :: Mesh(const Array<Point<3> >& ap,
                         Array<Point3d>& mp, double ghi,
                         class Mesh& mesh) const
{
    static int timer1a = NgProfiler::CreateTimer ("mesh stl-line 1a");
    static int timer1b = NgProfiler::CreateTimer ("mesh stl-line 1b");
    static int timer2 = NgProfiler::CreateTimer ("mesh stl-line 2");
    static int timer3 = NgProfiler::CreateTimer ("mesh stl-line 3");

    NgProfiler::StartTimer (timer1a);

    STLLine* line = new STLLine(geometry);

    //stlgh = ghi; //uebergangsloesung!!!!

    double len = GetLength(ap);
    double inthl = 0; //integral of 1/h
    double dist = 0;
    double h;
    int ind;
    Point3d p;

    Box<3> bbox;
    GetBoundingBox (ap, bbox);
    double diam = bbox.Diam();

    double minh = mesh.LocalHFunction().GetMinH (bbox.PMin(), bbox.PMax());

    double maxseglen = 0;
    for (int i = 1; i <= GetNS(); i++)
        maxseglen = max2 (maxseglen, GetSegLen (ap, i));

    int nph = 10+int(maxseglen / minh); //anzahl der integralauswertungen pro segment

    Array<double> inthi(GetNS()*nph);
    Array<double> curvelen(GetNS()*nph);

    NgProfiler::StopTimer (timer1a);
    NgProfiler::StartTimer (timer1b);


    for (int i = 1; i <= GetNS(); i++)
    {
        //double seglen = GetSegLen(ap,i);
        for (int j = 1; j <= nph; j++)
        {
            p = GetPointInDist(ap,dist,ind);
            //h = GetH(p,dist/len);
            h = mesh.GetH(p);


            dist += GetSegLen(ap,i)/(double)nph;

            inthl += GetSegLen(ap,i)/nph/(h);
            inthi.Elem((i-1)*nph+j) = GetSegLen(ap,i)/nph/h;
            curvelen.Elem((i-1)*nph+j) = GetSegLen(ap,i)/nph;
        }
    }


    int inthlint = int(inthl+1);

    if ( (inthlint < 3) && (StartP() == EndP()))
    {
        inthlint = 3;
    }
    if ( (inthlint == 1) && ShouldSplit())
    {
        inthlint = 2;
    }

    double fact = inthl/(double)inthlint;
    dist = 0;
    int j = 1;


    p = ap.Get(StartP());
    int pn = AddPointIfNotExists(mp, p, 1e-10*diam);

    int segn = 1;
    line->AddPoint(pn);
    line->AddLeftTrig(GetLeftTrig(segn));
    line->AddRightTrig(GetRightTrig(segn));
    line->AddDist(dist);

    NgProfiler::StopTimer (timer1b);
    NgProfiler::StartTimer (timer2);

    inthl = 0; //restart each meshseg
    for (int i = 1; i <= inthlint; i++)
    {
        while (inthl < 1.000000001 && j <= inthi.Size())
        {
            inthl += inthi.Get(j)/fact;
            dist += curvelen.Get(j);
            j++;
        }

        //went too far:
        j--;
        double tofar = (inthl - 1)/inthi.Get(j);
        inthl -= tofar*inthi.Get(j);
        dist -= tofar*curvelen.Get(j)*fact;

        if (i == inthlint && fabs(dist - len) >= 1E-8)
        {
            PrintSysError("meshline failed!!!");
        }

        if (i != inthlint)
        {
            p = GetPointInDist(ap,dist,ind);
            pn = AddPointIfNotExists(mp, p, 1e-10*diam);
            segn = ind;
            line->AddPoint(pn);
            line->AddLeftTrig(GetLeftTrig(segn));
            line->AddRightTrig(GetRightTrig(segn));
            line->AddDist(dist);
        }

        inthl = tofar*inthi.Get(j);
        dist += tofar*curvelen.Get(j)*fact;
        j++;
    }

    NgProfiler::StopTimer (timer2);
    NgProfiler::StartTimer (timer3);


    p = ap.Get(EndP());
    pn = AddPointIfNotExists(mp, p, 1e-10*diam);
    segn = GetNS();
    line->AddPoint(pn);
    line->AddLeftTrig(GetLeftTrig(segn));
    line->AddRightTrig(GetRightTrig(segn));
    line->AddDist(dist);

    for (int ii = 1; ii <= line->GetNS(); ii++)
    {
        int p1, p2;
        line->GetSeg(ii,p1,p2);
    }
    /*
    (*testout) << "line, " << ap.Get(StartP()) << "-" << ap.Get(EndP())
         << " len = " << Dist (ap.Get(StartP()), ap.Get(EndP())) << endl;
    */

    NgProfiler::StopTimer (timer3);

    return line;
}