コード例 #1
0
void MagicView::OnUpdateTextureMap(CCmdUI* pCmdUI) 
{
   Solid*      solid = GetDocument()->GetSolid();
   Selection*  seln  = GetDocument()->GetSelection();

   pCmdUI->Enable(solid && solid->GetModel() && seln && seln->GetPolys().size() > 0);
}
コード例 #2
0
void ForceValidityVisitor::visit( Solid& g )
{
    g.forceValidityFlag( valid_ );
    for ( size_t i = 0; i < g.numShells(); i++ ) {
        visit( g.shellN( i ) );
    }
}
コード例 #3
0
void MagicView::OnTextureMap() 
{
   TextureMapDialog dlg(this);
   if (dlg.DoModal() == IDOK) {
      MagicDoc*   doc      = GetDocument();
      Solid*      solid    = doc->GetSolid();
      Selection*  seln     = doc->GetSelection();
      Selector*   selector = doc->GetSelector();
      Editor*     editor   = doc->GetEditor();
      Material*   mtl      = 0;

      if (dlg.mMaterialIndex >= 0) {
         mtl = &solid->GetModel()->GetMaterials()[dlg.mMaterialIndex];
      }

      editor->UseModel(solid->GetModel());
      editor->ApplyMaterial(mtl, seln->GetPolys(),
                      dlg.mMapType, 2-dlg.mAxis, (float) dlg.mScaleU, (float) dlg.mScaleV,
                      dlg.mFlip, dlg.mMirror, dlg.mRotate);

      selector->Reselect();

      Invalidate();
      doc->SetModifiedFlag(TRUE);
      doc->UpdateAllViews(this);
   }
}
コード例 #4
0
void SingularPoint :: FindPoints (class Mesh & mesh)
{
  points.SetSize(0);
  ARRAY<int> surfk, surf;


  for (PointIndex pi = PointIndex::BASE; 
       pi < mesh.GetNP()+PointIndex::BASE; pi++)
    {
      if (mesh[pi].Type() != FIXEDPOINT) continue;
      const Point<3> p = mesh[pi];

      (*testout) << "check singular point" << p << endl;

      if (sol1->IsIn (p) && sol2->IsIn(p) && sol3->IsIn(p) &&
	  !sol1->IsStrictIn (p) && !sol2->IsStrictIn(p) && !sol3->IsStrictIn(p))
	{
	  surf.SetSize (0);
	  for (int k = 1; k <= 3; k++)
	    {
	      const Solid * solk;
	      Solid *tansol;
	      switch (k)
		{
		case 1:  solk = sol1; break;
		case 2:  solk = sol2; break;
		case 3:  solk = sol3; break;
		}

	      solk -> TangentialSolid (p, tansol, surfk, 1e-3);
	      (*testout) << "Tansol = " << *tansol << endl;

	      if (!tansol) continue;

	      ReducePrimitiveIterator rpi(Box<3> (p-Vec<3> (1e-3,1e-3,1e-3),
						  p+Vec<3> (1e-3,1e-3,1e-3)));
	      UnReducePrimitiveIterator urpi;
	      
	      tansol -> IterateSolid (rpi);
	      tansol->GetSurfaceIndices (surfk);
	      tansol -> IterateSolid (urpi);

	      (*testout) << "surfinds = " << surfk << endl;

	      for (int i = 0; i < surfk.Size(); i++)
		if (!surf.Contains (surfk[i]))
		  surf.Append (surfk[i]);
	      
	      delete tansol;
	    }

	  if (surf.Size() < 3) continue;

	  points.Append (p);
	  PrintMessage (5, "Point (", p(0), ", ", p(1), ", ", p(2), ") is singular");
	  mesh[pi].Singularity(factor);
	}
    }  
}
コード例 #5
0
ファイル: AffineTransform3.cpp プロジェクト: Ezio47/SFCGAL
void AffineTransform3::transform( Solid& solid )
{
    transform( solid.exteriorShell() );

    for ( size_t i = 0; i < solid.numInteriorShells(); ++i ) {
        transform( solid.interiorShellN( i ) );
    }
}
コード例 #6
0
ファイル: Solid.cpp プロジェクト: DArtagan/C--
// Compare two solids by volume using <=
bool operator<=( const Solid& lhs, const Solid& rhs )
{
    if( lhs.volume() <= rhs.volume() ) {
        return true;
    } else {
        return false;
    }
}
コード例 #7
0
void triangulatePolygon3D(
    const Solid& g,
    TriangulatedSurface& triangulatedSurface
)
{
    for ( size_t i = 0; i < g.numShells(); i++ ) {
        triangulatePolygon3D( g.shellN( i ), triangulatedSurface );
    }
}
コード例 #8
0
ファイル: cad2d.cpp プロジェクト: liminchen/VirtualStudio
	// generate a solid at the point p
	// the solid has a vertex, a face, a loop but no edges
	Solid* Solid::mvfs(Vertex* newv)
	{
		Solid *s = new Solid();
		Face *newf = new Face(s);
		Loop* newl = new Loop();
		s->addVertex(newv);
		s->addFace(newf);
		newf->addLoop(newl);

		return s;
	}
コード例 #9
0
ファイル: CSGWorld.cpp プロジェクト: andreaswatch/dizuo
void CSGWorld::Render()
{
	for(int i = 0; i < m_Solids.size(); i++)
	{
		Solid * pSolid = m_Solids[i];

		if(m_RenderSwitchboard[i])
		{
			pSolid->Render();
		}
	}
}
コード例 #10
0
void MagicView::CloseUVEditor()
{
   if (IsUVEdit()) {
      MagicDoc*   doc      = GetDocument();
      Editor*     editor   = doc->GetEditor();
      Solid*      solid    = doc->GetSolid();

      if (editor && solid) {
         editor->UseModel(solid->GetModel());
         editor->Resegment();
      }
   }
}
コード例 #11
0
ファイル: group.cpp プロジェクト: philippedax/vreng
int Group::Collide(Solid& moving) const
{
  if (!GetBoundingSphere().Collide(moving.GetBoundingSphere())) return 0;
  if (!GetBoundingBox().Collide(moving.GetBoundingBox())) return 0; 

  for (int i=0; i < GetCard() ; i++) {
    Solid* other=group[i];
    if (other==&moving) continue;
    if (!other->GetBoundingSphere().Collide(moving.GetBoundingSphere())) continue;
    if (!other->GetBoundingBox().Collide(moving.GetBoundingBox())) continue;
    return 1;
  }
  return 0;
}
コード例 #12
0
void MagicView::OnSelectInverse() 
{
   Solid*      solid    = GetDocument()->GetSolid();
   Selector*   selector = GetDocument()->GetSelector();

   if (IsUVEdit()) {
      uvmap_view->SelectInverse();
   }

   else if (solid && selector) {
      selector->UseModel(solid->GetModel());
      selector->SelectInverse();
   }
}
コード例 #13
0
ファイル: Utilities.cpp プロジェクト: AIDASoft/DD4hep
/// Create a solid shape using the plugin mechanism from the attributes of the XML element
Solid dd4hep::xml::createShape(Detector& description,
                               const std::string& shape_type,
                               xml::Element element)   {
  string fac  = shape_type + "__shape_constructor";
  xml::Handle_t solid_elt = element;
  Solid solid = Solid(PluginService::Create<TObject*>(fac, &description, &solid_elt));
  if ( !solid.isValid() )  {
    PluginDebug dbg;
    PluginService::Create<TObject*>(fac, &description, &solid_elt);
    except("xml::createShape","Failed to create solid of type %s [%s]", 
           shape_type.c_str(),dbg.missingFactory(shape_type).c_str());
  }
  return solid;
}
コード例 #14
0
void MagicView::OnSelectNone() 
{
   Solid*      solid    = GetDocument()->GetSolid();
   Selector*   selector = GetDocument()->GetSelector();

   if (IsUVEdit()) {
      uvmap_view->SelectNone();
   }

   else if (solid && selector) {
      selector->UseModel(solid->GetModel());
      selector->SelectAll(Selector::SELECT_REMOVE);
   }
}
コード例 #15
0
ファイル: BlueprintInstance.cpp プロジェクト: sub77/hobbycode
Solid * BlueprintInstance::detachSolid(unsigned int i)
{
    assert(i < mSolidList.size());
    Solid * detached = mSolidList[i];

    // detach from list
    mSolidList.erase(mSolidList.begin() + i);

    // detach from map
    map<string, Solid*>::iterator iter =
        mSolidMap.find(detached->getName());
    mSolidMap.erase(iter);

    return detached;
}
コード例 #16
0
ファイル: features.hpp プロジェクト: anylonen/abura-tan
        static Target create( const Option& o )
        {

            Solid* solid = new Solid( &o );
            TargetValue* THIS = new TargetValue( solid );
            solid->setTHIS(THIS);

            Target target = THIS;

            solid->build(o);

            //l.addFeature( target );

            return Target(target);
        }
コード例 #17
0
ファイル: distance3d.cpp プロジェクト: Oslandia/SFCGAL
double distanceTriangleSolid3D( const Triangle& gA, const Solid& gB )
{
    if ( gA.isEmpty() || gB.isEmpty() ) {
        return std::numeric_limits< double >::infinity() ;
    }

    if ( intersects3D( gA, gB, NoValidityCheck() ) ) {
        return 0.0 ;
    }

    double dMin = std::numeric_limits< double >::infinity() ;

    for ( size_t i = 0; i < gB.numShells(); i++ ) {
        dMin = std::min( dMin, gB.shellN( i ).distance3D( gA ) );
    }

    return dMin ;
}
コード例 #18
0
void MagicView::OnEditRedo() 
{
   MagicDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
   pDoc->Redo();

   Solid*      solid    = GetDocument()->GetSolid();
   Selector*   selector = GetDocument()->GetSelector();

   if (selector) {
      selector->UseModel(solid->GetModel());
      selector->Reselect();
   }

   Invalidate();
   pDoc->SetModifiedFlag(TRUE);
   pDoc->UpdateAllViews(this);
}
コード例 #19
0
void MagicView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) 
{
   CView::OnUpdate(pSender, lHint, pHint);

   Solid*      solid    = GetDocument()->GetSolid();
   Selection*  seln     = GetDocument()->GetSelection();
   Selector*   selector = GetDocument()->GetSelector();

   if (solid && scene) {
      scene->Graphics().clear();
      scene->AddGraphic(solid);
      scene->AddGraphic(seln);
      scene->AddGraphic(selector);
   }

   if (selector)
      selector->UseModel(solid->GetModel());
}
コード例 #20
0
ファイル: distance3d.cpp プロジェクト: Oslandia/SFCGAL
double distancePointSolid3D( const Point& gA, const Solid& gB )
{
    if ( gA.isEmpty() || gB.isEmpty() ) {
        return std::numeric_limits< double >::infinity() ;
    }

    if ( intersects3D( gA, gB, NoValidityCheck() ) ) {
        return 0.0 ;
    }

    double dMin = std::numeric_limits< double >::infinity() ;

    for ( size_t i = 0; i < gB.numShells(); i++ ) {
        dMin = std::min( dMin, distanceGeometryCollectionToGeometry3D( gB.shellN( i ), gA ) );
    }

    return dMin ;
}
コード例 #21
0
ファイル: volume.cpp プロジェクト: HEShuang/SFCGAL
const Kernel::FT volume( const Solid& solid, NoValidityCheck )
{
    Kernel::FT vol = 0;
    const CGAL::Point_3<Kernel> origin( 0,0,0 );
    const size_t numShells = solid.numShells();

    for ( size_t i=0; i<numShells; i++ ) {
        std::auto_ptr<Geometry> t( tesselate( solid.shellN( i ), NoValidityCheck() ) );
        const TriangulatedSurface& tin = t->as<TriangulatedSurface>();
        const size_t numTriangles = tin.numTriangles();

        for ( size_t j=0; j<numTriangles; j++ ) {
            const Triangle& tri = tin.triangleN( j );
            vol = vol + CGAL::volume( origin, tri.vertex( 0 ).toPoint_3(),
                                      tri.vertex( 1 ).toPoint_3(),
                                      tri.vertex( 2 ).toPoint_3() );
        }
    }

    return vol;
}
コード例 #22
0
ファイル: VelocityMotor.cpp プロジェクト: sub77/hobbycode
    void VelocityMotor::internal_update()
    {
        // check if we have a solid
        if (mData.solid == NULL || isEnabled() == false) return ;

        Vec3r targetVelocity = mData.velocity;
        Solid * solid = mData.solid;

        Vec3r currentAchievedVelocity = solid->getGlobalLinearVel();

        if (doesGravityAffectSolid())
        {
            Vec3r gravity = mSimulator->getGravity();
            if (gravity.length() > 0)
            {
                Vec3r gravity_velocity = project(gravity, currentAchievedVelocity);
                currentAchievedVelocity -= gravity_velocity;
            }
        }

        Vec3r deltaVelocity = targetVelocity - currentAchievedVelocity;

        Vec3r forceVector = deltaVelocity / mSimulator->getStepSize() * solid->getMass();
        if (!doesGravityAffectSolid())
            forceVector -= mSimulator->getGravity() * solid->getMass();

        if (forceVector.length() > getMaximumForce())
        {
            forceVector.normalize();
            forceVector *= getMaximumForce();
        }

        Force controllingForce;
        controllingForce.duration = 0;
        controllingForce.singleStep = true;
        controllingForce.type = GLOBAL_FORCE;
        controllingForce.vec = forceVector;

        solid->addForce(controllingForce);
    }
コード例 #23
0
ファイル: Weapon.cpp プロジェクト: Banbury/starshatter-open
void
Weapon::SetOwner(Ship* s)
{
    ship = s;

    if (design->turret_model) {
        Solid* t = new(__FILE__,__LINE__) Solid;
        t->UseModel(design->turret_model);
        turret = t;
    }

    if (design->turret_base_model) {
        Solid* t = new(__FILE__,__LINE__) Solid;
        t->UseModel(design->turret_base_model);
        turret_base = t;
    }

    if (!design->primary          && 
            design->visible_stores   &&
            ammo == nbarrels         &&
            design->shot_model != 0)
    {
        for (int i = 0; i < nbarrels; i++) {
            Solid* s = new(__FILE__,__LINE__) Solid;
            s->UseModel(design->shot_model);

            visible_stores[i] = s;
        }
    }
}
コード例 #24
0
 void Destroyable::simulate(const float& i_seconds)
 {
   if (getTrait()->getLife() <= 0 && !m_marked_to_destroy)
   {
     InternalMessage("Model","Logic::Destroyable destroying object") ;
     
     // create explosion
     Solid* solid = getObject()->getTrait<Solid>() ;
     Distance explosion_radius ;
     
     if (solid)
       explosion_radius = 4*solid->getRadius() ;
     
     Duration explosion_duration(Duration::Second(1)) ;
     getObject()->addTrait(new Explosion(explosion_radius,explosion_duration)) ;
     
     // add a life time trait
     getObject()->addTrait(new WithLifetime(explosion_duration)) ;
     
     m_marked_to_destroy = true ;
   }
 }
コード例 #25
0
ファイル: distance3d.cpp プロジェクト: Oslandia/SFCGAL
double distanceSolidSolid3D( const Solid& gA, const Solid& gB )
{
    //SFCGAL_DEBUG( boost::format("dispatch distancePolygonGeometry3D(%s,%s)") % gA.asText() % gB.asText() );

    if ( gA.isEmpty() || gB.isEmpty() ) {
        return std::numeric_limits< double >::infinity() ;
    }

    if ( intersects( gA, gB, NoValidityCheck() ) ) {
        return 0.0 ;
    }

    double dMin = std::numeric_limits< double >::infinity() ;

    for ( size_t i = 0; i < gA.numShells(); i++ ) {
        for ( size_t j = 0; j < gB.numShells(); j++ ) {
            dMin = std::min( dMin, gA.shellN( i ).distance3D( gB.shellN( j ) ) );
        }
    }

    return dMin ;
}
コード例 #26
0
ファイル: distance3d.cpp プロジェクト: Oslandia/SFCGAL
double distanceSolidGeometry3D( const Solid& gA, const Geometry& gB )
{
    //SFCGAL_DEBUG( boost::format("dispatch distanceSolidGeometry3D(%s,%s)") % gA.asText() % gB.asText() );

    switch ( gB.geometryTypeId() ) {
    case TYPE_POINT:
        return distancePointSolid3D( gB.as< Point >(), gA ); //symetric

    case TYPE_LINESTRING:
        return distanceLineStringSolid3D( gB.as< LineString >(), gA ); //symetric

    case TYPE_TRIANGLE:
        return distanceTriangleSolid3D( gB.as< Triangle >(), gA ); //symetric

    case TYPE_POLYGON:
        return distancePolygonGeometry3D( gB.as< Polygon >(), gA ); //symetric

    case TYPE_SOLID:
        return distanceSolidSolid3D( gA, gB.as< Solid >() );

    case TYPE_MULTIPOINT:
    case TYPE_MULTILINESTRING:
    case TYPE_MULTIPOLYGON:
    case TYPE_MULTISOLID:
    case TYPE_GEOMETRYCOLLECTION:
    case TYPE_TRIANGULATEDSURFACE:
    case TYPE_POLYHEDRALSURFACE:
        return distanceGeometryCollectionToGeometry3D( gB, gA );
    }

    BOOST_THROW_EXCEPTION( Exception(
                               ( boost::format( "distance3D(%s,%s) is not implemented" ) % gA.geometryType() % gB.geometryType() ).str()
                           ) );
}
コード例 #27
0
ファイル: minkowskiSum.cpp プロジェクト: hdeeken/SFCGAL
void minkowskiSum( const Solid& gA, const Polygon_2& gB, Polygon_set_2& polygonSet )
{
    //use only the projection of exterior shell
    minkowskiSumCollection( gA.exteriorShell(), gB, polygonSet );
}
コード例 #28
0
ファイル: GetPointsVisitor.cpp プロジェクト: HEShuang/SFCGAL
void GetPointsVisitor::visit( const Solid& g )
{
    for ( size_t i = 0; i < g.numShells(); i++ ) {
        visit( g.shellN( i ) );
    }
}
コード例 #29
0
void main(int argc, char *argv[])
{
	// Read in the obj file
	Solid mesh;
	OBJFileReader of;
	std::ifstream in(argv[1]);
	string filename = argv[1];
	string::size_type npos = filename.find(".obj");
	string s = ".m";
	filename.replace(npos, 4,s);
	of.readToSolid(&mesh, in);

	/******************* Put you subdivision processing here *********************/


	//1. highlights all edges  zz begin 2013-02-21 16:11:20

	SolidEdgeIterator eiter(&mesh);
	for(; !eiter.end(); ++eiter)
	{
		Edge *e = *eiter;
		e->string ()=std::string("sharp");
	}
	//end zz 2013Äê2ÔÂ21ÈÕ16:18:10

	//2. establish the adjacency list [2/21/2013 Zhe]
	list<int> Graphface[Num];
	SolidFaceIterator fiter(&mesh);
	for(; !fiter.end(); ++fiter)
	{
		Face *f = *fiter;
		FaceHalfedgeIterator hfiter(f);
		HalfEdge *hf = NULL;
		for (;!hfiter.end();++hfiter)
		{		
			hf = *hfiter;
			hf = hf->he_sym();
			Graphface[f->id()].push_back(hf->face()->id());
		}
	}
	//  [2/21/2013 Zhe]

	/************************************************************************/
	/* // 3.MST Algorithm [19:00/2/21/2013 Zhe]                                                                     */
	/************************************************************************/
	list<int> Mstqueue;
	queue<int> nLayer;
	list<int>::iterator mstiterator,Mstqueueiterator,Layeriterator;
	fiter.reset();
	int a[Num] = {0};

	Face *MSTface = *fiter;
	Mstqueue.push_back(MSTface->id());
	nLayer.push(MSTface->id()); //initialization
	a[MSTface->id()] = TRUE;
	while (!nLayer.empty())
	{
		int Faceid = nLayer.front();	
		nLayer.pop();
		//MstGraphface[Faceid].push_back(Faceid);
		for (mstiterator = Graphface[Faceid].begin();mstiterator != Graphface[Faceid].end();++mstiterator)
		{
			//Layeriterator = find (Mstqueue.begin(), Mstqueue.end(), *mstiterator);
			if (a[*mstiterator] == 0) 
			{
				Mstqueue.push_back(*mstiterator);
				nLayer.push(*mstiterator);
				a[*mstiterator] = TRUE;
				int nFaceid_father = Faceid;
				int nFaceId_son = *mstiterator;

				MeshLib::Face *f = mesh.idFace (nFaceid_father);
				MeshLib::FaceHalfedgeIterator fheiter(f);

				MeshLib::Edge * inter_edge;
				for (; !fheiter.end (); ++fheiter)
				{
					MeshLib::HalfEdge *he = *fheiter;
					he = he->he_sym ();
					if (he->face ()->id ()== nFaceId_son)
					{
						inter_edge=he->edge ();
						inter_edge->string () = std::string("");
						break;
					}
				}
			}
		}
	}



	// 3. cut the graph [23:19/2/21/2013 Zhe]
	SolidVertexIterator iter(&mesh);
	std::map<int, int> vidToObjID;

	do 
	{
		for(; !iter.end(); ++iter)
		{
			Vertex *v = *iter;
			MeshLib::VertexEdgeIterator edgeiter(v);
			MeshLib::Edge * inter_edge;
			int nsharp = 0;
			for (;!edgeiter.end();++edgeiter)
			{			
				inter_edge = *edgeiter;
				if (inter_edge->string() == "sharp")
				{
					nsharp++;
				}
			}


			//delete nsharp == 1
			if (1 == nsharp)
			{
				edgeiter.reset();
				for (;!edgeiter.end();++edgeiter)
				{			
					inter_edge = *edgeiter;
					if (inter_edge->string() == "sharp")
					{
						inter_edge->string () = std::string("");
						//nsharp = 0;
					}
				}

			}
			vidToObjID[v->id()] = nsharp;
		}
		iter.reset();

	} while (ifsharpequalone(vidToObjID));

	mesh.write (filename.c_str()); 

	//	os.close();
}
コード例 #30
0
ファイル: DDTIBLayerAlgo.cpp プロジェクト: AIDASoft/DD4hep
static long algorithm(Detector& /* description */,
                      ParsingContext& ctxt,
                      xml_h e,
                      SensitiveDetector& /* sens */)
{
  typedef vector<double> vecdouble;
  Namespace      ns(ctxt, e, true);
  AlgoArguments  args(ctxt, e);
  string    mother       = args.parentName();
  string    genMat       = args.str("GeneralMaterial");           //General material name
  double    detectorTilt = args.dble("DetectorTilt");             //Detector Tilt
  double    layerL       = args.dble("LayerL");                   //Length of the layer

  double    radiusLo     = args.dble("RadiusLo");                 //Radius for detector at lower level
  int       stringsLo    = args.integer("StringsLo");             //Number of strings      ......
  string    detectorLo   = args.str("StringDetLoName");           //Detector string name   ......

  double    radiusUp     = args.dble("RadiusUp");                 //Radius for detector at upper level
  int       stringsUp    = args.integer("StringsUp");             //Number of strings      ......
  string    detectorUp   = args.str("StringDetUpName");           //Detector string name   ......

  double    cylinderT    = args.dble("CylinderThickness");        //Cylinder thickness
  double    cylinderInR  = args.dble("CylinderInnerRadius");      //Cylinder inner radius
  string    cylinderMat  = args.str("CylinderMaterial");          //Cylinder material
  double    MFRingInR    = args.dble("MFRingInnerRadius");        //Inner Manifold Ring Inner Radius 
  double    MFRingOutR   = args.dble("MFRingOuterRadius");        //Outer Manifold Ring Outer Radius 
  double    MFRingT      = args.dble("MFRingThickness");          //Manifold Ring Thickness
  double    MFRingDz     = args.dble("MFRingDeltaz");             //Manifold Ring Half Lenght
  string    MFIntRingMat = args.str("MFIntRingMaterial");         //Manifold Ring Material
  string    MFExtRingMat = args.str("MFExtRingMaterial");         //Manifold Ring Material

  double    supportT     = args.dble("SupportThickness");         //Cylinder barrel CF skin thickness

  string    centMat      = args.str("CentRingMaterial");          //Central rings  material
  vecdouble centRing1par = args.vecDble("CentRing1");             //Central rings parameters
  vecdouble centRing2par = args.vecDble("CentRing2");             //Central rings parameters

  string    fillerMat    = args.str("FillerMaterial");            //Filler material
  double    fillerDz     = args.dble("FillerDeltaz");             //Filler Half Length

  string    ribMat       = args.str("RibMaterial");               //Rib material
  vecdouble ribW         = args.vecDble("RibWidth");              //Rib width
  vecdouble ribPhi       = args.vecDble("RibPhi");                //Rib Phi position

  vecdouble dohmListFW   = args.vecDble("DOHMListFW");            //DOHM/AUX positions in #strings FW
  vecdouble dohmListBW   = args.vecDble("DOHMListBW");            //DOHM/AUX positions in #strings BW

  double    dohmtoMF            = args.dble("DOHMtoMFDist");      //DOHM Distance to MF
  double    dohmCarrierPhiOff   = args.dble("DOHMCarrierPhiOffset"); //DOHM Carrier Phi offset wrt horizontal
  string    dohmPrimName        = args.str("StringDOHMPrimName"); //DOHM Primary Logical Volume name
  string    dohmAuxName         = args.str("StringDOHMAuxName");  //DOHM Auxiliary Logical Volume name

  string    dohmCarrierMaterial = args.str("DOHMCarrierMaterial");//DOHM Carrier Material
  string    dohmCableMaterial   = args.str("DOHMCableMaterial");  //DOHM Cable Material
  double    dohmPrimL           = args.dble("DOHMPRIMLength");    //DOHM PRIMary Length
  string    dohmPrimMaterial    = args.str("DOHMPRIMMaterial");   //DOHM PRIMary Material
  double    dohmAuxL            = args.dble("DOHMAUXLength");     //DOHM AUXiliary Length
  string    dohmAuxMaterial     = args.str("DOHMAUXMaterial");    //DOHM AUXiliary Material

  string    pillarMaterial      = args.str("PillarMaterial");     //Pillar Material

  double    fwIntPillarDz       = args.dble("FWIntPillarDz");     //Internal pillar parameters
  double    fwIntPillarDPhi     = args.dble("FWIntPillarDPhi");  
  vecdouble fwIntPillarZ        = args.vecDble("FWIntPillarZ");  
  vecdouble fwIntPillarPhi      = args.vecDble("FWIntPillarPhi");  
  double    bwIntPillarDz       = args.dble("BWIntPillarDz");  
  double    bwIntPillarDPhi     = args.dble("BWIntPillarDPhi");  
  vecdouble bwIntPillarZ        = args.vecDble("BWIntPillarZ");  
  vecdouble bwIntPillarPhi      = args.vecDble("BWIntPillarPhi");  

  double    fwExtPillarDz       = args.dble("FWExtPillarDz");        //External pillar parameters
  double    fwExtPillarDPhi     = args.dble("FWExtPillarDPhi");  
  vecdouble fwExtPillarZ        = args.vecDble("FWExtPillarZ");    
  vecdouble fwExtPillarPhi      = args.vecDble("FWExtPillarPhi");  
  double    bwExtPillarDz       = args.dble("BWExtPillarDz");  
  double    bwExtPillarDPhi     = args.dble("BWExtPillarDPhi");  
  vecdouble bwExtPillarZ        = args.vecDble("BWExtPillarZ");    
  vecdouble bwExtPillarPhi      = args.vecDble("BWExtPillarPhi");  
  
  LogDebug("TIBGeom") << "Parent " << mother
      << " NameSpace " << ns.name
      << " General Material " << genMat;
  LogDebug("TIBGeom") << "Lower layer Radius " << radiusLo
      << " Number " << stringsLo << " String " << detectorLo;
  LogDebug("TIBGeom") << "Upper layer Radius "<< radiusUp
      << " Number " << stringsUp << " String " << detectorUp;
  LogDebug("TIBGeom") << "Cylinder Material/thickness " << cylinderMat << " " << cylinderT 
      << " Rib Material " << ribMat << " at " << ribW.size() << " positions with width/phi";
  for (unsigned int i = 0; i < ribW.size(); i++)  {
    LogDebug("TIBGeom") << "\tribW[" << i << "] = " <<  ribW[i] 
        << "\tribPhi[" << i << "] = " << ribPhi[i]/CLHEP::deg;
  }
  LogDebug("TIBGeom") << "DOHM Primary " << " Material " << dohmPrimMaterial << " Length " << dohmPrimL;
  LogDebug("TIBGeom") << "DOHM Aux     " << " Material " << dohmAuxMaterial << " Length " << dohmAuxL;
  for (double i : dohmListFW) {
    if (i>0.) LogDebug("TIBGeom") << "DOHM Primary at FW Position " << i;
    if (i<0.) LogDebug("TIBGeom") << "DOHM Aux     at FW Position " << -i;
  }
  for (double i : dohmListBW) {
    if (i>0.) LogDebug("TIBGeom") << "DOHM Primary at BW Position " << i;
    if (i<0.) LogDebug("TIBGeom") << "DOHM Aux     at BW Position " << -i;
  }
  LogDebug("TIBGeom") << "FW Internal Pillar [Dz, DPhi] " << fwIntPillarDz << ", " << fwIntPillarDPhi; 
  for (unsigned int i=0; i<fwIntPillarZ.size(); i++) {
    if( fwIntPillarPhi[i]>0. ) { 
      LogDebug("TIBGeom") << " at positions [z, phi] " << fwIntPillarZ[i] << " " << fwIntPillarPhi[i];
    }
  }
  LogDebug("TIBGeom") << "BW Internal Pillar [Dz, DPhi] " << bwIntPillarDz << ", " << bwIntPillarDPhi; 
  for (unsigned int i=0; i<bwIntPillarZ.size(); i++) {
    if( bwIntPillarPhi[i]>0. ) { 
      LogDebug("TIBGeom") << " at positions [z, phi] " << bwIntPillarZ[i] << " " << bwIntPillarPhi[i];
    }
  }
  LogDebug("TIBGeom") << "FW External Pillar [Dz, DPhi] " << fwExtPillarDz << ", " << fwExtPillarDPhi; 
  for (unsigned int i=0; i<fwExtPillarZ.size(); i++) {
    if( fwExtPillarPhi[i]>0. ) { 
      LogDebug("TIBGeom") << " at positions [z, phi] " << fwExtPillarZ[i] << " " << fwExtPillarPhi[i];
    }
  }
  LogDebug("TIBGeom") << "BW External Pillar [Dz, DPhi] " << bwExtPillarDz << ", " << bwExtPillarDPhi; 
  for (unsigned int i=0; i<bwExtPillarZ.size(); i++) {
    if( bwExtPillarPhi[i]>0. ) { 
      LogDebug("TIBGeom") << " at positions [z, phi] " << bwExtPillarZ[i] << " " << bwExtPillarPhi[i];
    }
  }

  string idName = mother;
  double rmin = MFRingInR;
  double rmax = MFRingOutR;
  Solid  solid = ns.addSolidNS(idName,Tube(rmin, rmax, 0.5*layerL));
  LogDebug("TIBGeom") << solid.name() << " Tubs made of " 
      << genMat << " from 0 to " << CLHEP::twopi/CLHEP::deg 
      << " with Rin " << rmin << " Rout " << rmax << " ZHalf " << 0.5*layerL;
  Volume layer = ns.addVolumeNS(Volume(idName, solid, ns.material(genMat)));

  //Internal layer first
  double rin  = rmin+MFRingT;
  //  double rout = 0.5*(radiusLo+radiusUp-cylinderT);
  double rout = cylinderInR;
  string name = idName + "Down";
  solid = ns.addSolidNS(name,Tube(rin, rout, 0.5*layerL));
  LogDebug("TIBGeom") << solid.name() << " Tubs made of " 
      << genMat << " from 0 to " << CLHEP::twopi/CLHEP::deg 
      << " with Rin " << rin << " Rout " << rout 
      << " ZHalf " << 0.5*layerL;
  Volume layerIn = ns.addVolumeNS(Volume(name, solid, ns.material(genMat)));
  layer.placeVolume(layerIn, 1); // copyNr=1 !
  LogDebug("TIBGeom") << layerIn.name()
      << " number 1 positioned in " << layer.name()
      << " at (0,0,0) with no rotation";

  double rposdet = radiusLo;
  double dphi    = CLHEP::twopi/stringsLo;
  Volume detIn   = ns.volume(detectorLo);
  for (int n = 0; n < stringsLo; n++) {
    double phi    = (n+0.5)*dphi;
    double phix   = phi - detectorTilt + 90*CLHEP::deg;
    double theta  = 90*CLHEP::deg;
    double phiy   = phix + 90.*CLHEP::deg;
    Rotation3D rotation = make_rotation3D(theta, phix, theta, phiy, 0., 0.);
    Position   trdet(rposdet*cos(phi), rposdet*sin(phi), 0);
    layerIn.placeVolume(detIn, n+1, Transform3D(rotation,trdet)); // copyNr=n+1
    LogDebug("TIBGeom") << detIn.name() << " number " << n+1 << " positioned in " 
        << layerIn.name() << " at " << trdet << " with "
        << rotation;
  }
  //Now the external layer
  rin  = cylinderInR + cylinderT;
  rout = rmax-MFRingT;
  name = idName + "Up";
  solid = ns.addSolidNS(name,Tube(rin, rout, 0.5*layerL));
  LogDebug("TIBGeom") << solid.name() << " Tubs made of " 
      << genMat << " from 0 to " << CLHEP::twopi/CLHEP::deg 
      << " with Rin " << rin << " Rout " << rout
      << " ZHalf " << 0.5*layerL;
  Volume layerOut = ns.addVolumeNS(Volume(name, solid, ns.material(genMat)));
  layer.placeVolume(layerOut, 1); // CopyNr 1 
  LogDebug("TIBGeom") << layerOut.name() 
      << " number 1 positioned in " << layer.name() 
      << " at (0,0,0) with no rotation";

  rposdet = radiusUp;
  dphi    = CLHEP::twopi/stringsUp;
  Volume detOut = ns.volume(detectorUp);
  for (int n = 0; n < stringsUp; n++) {
    double phi    = (n+0.5)*dphi;
    double phix   = phi - detectorTilt - 90*CLHEP::deg;
    double theta  = 90*CLHEP::deg;
    double phiy   = phix + 90.*CLHEP::deg;
    Rotation3D rotation = make_rotation3D(theta, phix, theta, phiy, 0., 0.);
    Position   trdet(rposdet*cos(phi), rposdet*sin(phi), 0);
    layerOut.placeVolume(detOut, n+1, Transform3D(rotation,trdet));
    LogDebug("TIBGeom") << "DDTIBLayerAlgo test " << detectorUp
        << " number " << n+1 << " positioned in " 
        << layerOut.name() << " at " << trdet << " with "
        << rotation;
  }

  //
  // Inner cylinder, support wall and ribs
  //
  // External skins
  rin   = cylinderInR;
  rout  = cylinderInR+cylinderT;
  name  = idName + "Cylinder";
  solid = ns.addSolidNS(name, Tube(rin, rout, 0.5*layerL));
  LogDebug("TIBGeom") << solid.name() << " Tubs made of " 
      << cylinderMat << " from 0 to " 
      << CLHEP::twopi/CLHEP::deg << " with Rin " << rin 
      << " Rout " << rout << " ZHalf " << 0.5*layerL;
  Volume cylinder = ns.addVolumeNS(Volume(name, solid, ns.material(cylinderMat)));
  layer.placeVolume(cylinder, 1); // CopyNr = 1
  LogDebug("TIBGeom") << cylinder.name() 
      << " number 1 positioned in " << layer.name()
      << " at (0,0,0) with no rotation";
  //
  // inner part of the cylinder
  //
  rin  += supportT;
  rout -= supportT;
  name  = idName + "CylinderIn";
  solid = ns.addSolidNS(name, Tube(rin, rout, 0.5*layerL));
  LogDebug("TIBGeom") << solid.name() << " Tubs made of "
      << genMat << " from 0 to " << CLHEP::twopi/CLHEP::deg 
      << " with Rin " << rin << " Rout " << rout 
      << " ZHalf " << 0.5*layerL;
  Volume cylinderIn = ns.addVolumeNS(Volume(name, solid, ns.material(genMat)));
  cylinder.placeVolume(cylinderIn, 1);
  LogDebug("TIBGeom") << cylinderIn.name() 
      << " number 1 positioned in " << cylinder.name() 
      << " at (0,0,0) with no rotation";
  //
  // Filler Rings
  //
  name = idName + "Filler";
  solid = ns.addSolidNS(name,Tube(rin, rout, fillerDz));
  LogDebug("TIBGeom") << solid.name() << " Tubs made of " 
      << fillerMat << " from " << 0. << " to "
      << CLHEP::twopi/CLHEP::deg << " with Rin " << rin 
      << " Rout " << rout << " ZHalf "  << fillerDz;
  Volume cylinderFiller = ns.addVolumeNS(Volume(name,solid,ns.material(fillerMat)));
  cylinderIn.placeVolume(cylinderFiller, 1, Position(0.0, 0.0, 0.5*layerL-fillerDz)); // copyNr 1
  cylinderIn.placeVolume(cylinderFiller, 2, Position(0.0, 0.0,-0.5*layerL+fillerDz)); // copyNr 2
  LogDebug("TIBGeom") << "DDTIBLayerAlgo test " << cylinderFiller.name()
      << " number 1" << " positioned in " 
      << cylinderIn.name() << " at " << Position(0.0, 0.0, 0.5*layerL-fillerDz)
      << " number 2" << " positioned in " 
      << cylinderIn.name() << " at " << Position(0.0, 0.0,-0.5*layerL+fillerDz);
  //
  // Ribs
  //
  Material matrib = ns.material(ribMat);
  for (size_t i = 0; i < ribW.size(); i++) {
    name = idName + "Rib" + std::to_string(i);
    double width = 2.*ribW[i]/(rin+rout);
    double dz    = 0.5*layerL-2.*fillerDz;
    double _rmi  = std::min(rin+0.5*CLHEP::mm,rout-0.5*CLHEP::mm);
    double _rma  = std::max(rin+0.5*CLHEP::mm,rout-0.5*CLHEP::mm);
    solid = ns.addSolidNS(name,Tube(_rmi,_rma,dz,-0.5*width, width));
    LogDebug("TIBGeom") << solid.name() << " Tubs made of " 
        << ribMat << " from " << -0.5*width/CLHEP::deg <<" to "
        << 0.5*width/CLHEP::deg << " with Rin " 
        << rin+0.5*CLHEP::mm << " Rout " 
        << rout-0.5*CLHEP::mm << " ZHalf "  << dz;
    Volume cylinderRib = ns.addVolumeNS(Volume(name, solid, matrib));
    double phix   = ribPhi[i];
    double theta  = 90*CLHEP::deg;
    double phiy   = phix + 90.*CLHEP::deg;
    Rotation3D rotation = make_rotation3D(theta, phix, theta, phiy, 0., 0.);
    Position tran(0, 0, 0);
    cylinderIn.placeVolume(cylinderRib, 1, Transform3D(rotation,tran));// copyNr=1
    LogDebug("TIBGeom") << cylinderRib.name()
        << " number 1" << " positioned in " 
        << cylinderIn.name() << " at " << tran << " with " 
        << rotation;
  }
  //
  //Manifold rings
  //
  // Inner ones first
  rin   = MFRingInR;
  rout  = rin + MFRingT;
  name  = idName + "InnerMFRing";
  solid = ns.addSolidNS(name,Tube(rin, rout, MFRingDz));
  LogDebug("TIBGeom") << solid.name() << " Tubs made of " 
      << MFIntRingMat << " from 0 to " 
      << CLHEP::twopi/CLHEP::deg << " with Rin " << rin 
      << " Rout " << rout << " ZHalf " << MFRingDz;
  Volume inmfr = ns.addVolumeNS(Volume(name, solid, ns.material(MFIntRingMat)));
  layer.placeVolume(inmfr, 1, Position(0.0, 0.0, -0.5*layerL+MFRingDz)); // Copy Nr=1
  layer.placeVolume(inmfr, 2, Position(0.0, 0.0, +0.5*layerL+MFRingDz)); // Copy Nr=2
  LogDebug("TIBGeom") << inmfr.name() 
      << " number 1 and 2 positioned in " << layer.name()
      << " at (0,0,+-" << 0.5*layerL-MFRingDz << ") with no rotation";

  // Outer ones
  rout = MFRingOutR;
  rin  = rout - MFRingT;
  name = idName + "OuterMFRing";
  solid= ns.addSolidNS(name,Tube(rin, rout, MFRingDz));
  LogDebug("TIBGeom") << solid.name() << " Tubs made of " 
      << MFExtRingMat << " from 0 to " 
      << CLHEP::twopi/CLHEP::deg << " with Rin " << rin 
      << " Rout " << rout << " ZHalf " << MFRingDz;

  Volume outmfr = ns.addVolumeNS(Volume(name, solid, ns.material(MFExtRingMat)));
  layer.placeVolume(outmfr, 1, Position(0.0, 0.0, -0.5*layerL+MFRingDz)); // CopyNr=1
  layer.placeVolume(outmfr, 2, Position(0.0, 0.0, +0.5*layerL+MFRingDz)); // CopyNr=2
  LogDebug("TIBGeom") << outmfr.name() 
      << " number 1 and 2 positioned in " << layer.name()
      << " at (0,0,+-" << 0.5*layerL-MFRingDz 
      << ") with no rotation";
  //
  //Central Support rings
  //
  // Ring 1
  double centZ  = centRing1par[0];
  double centDz = 0.5*centRing1par[1];
  rin  = centRing1par[2];
  rout = centRing1par[3];
  name = idName + "CentRing1";
  solid = ns.addSolidNS(name,Tube(rin, rout, centDz));

  LogDebug("TIBGeom") << solid.name() << " Tubs made of " 
      << centMat << " from 0 to " << CLHEP::twopi/CLHEP::deg 
      << " with Rin " << rin << " Rout " << rout 
      << " ZHalf " << centDz;

  Volume cent1 = ns.addVolumeNS(Volume(name, solid, ns.material(centMat)));
  layer.placeVolume(cent1,1, Position(0.0, 0.0, centZ)); // Copy Nr = 1
  LogDebug("TIBGeom") << cent1.name() << " positioned in " << layer.name()
      << " at (0,0," << centZ << ") with no rotation";
  // Ring 2
  centZ  = centRing2par[0];
  centDz = 0.5*centRing2par[1];
  rin  = centRing2par[2];
  rout = centRing2par[3];
  name = idName + "CentRing2";
  solid = ns.addSolidNS(name, Tube(rin, rout, centDz));
  LogDebug("TIBGeom") << solid.name() << " Tubs made of " 
      << centMat << " from 0 to " << CLHEP::twopi/CLHEP::deg 
      << " with Rin " << rin << " Rout " << rout 
      << " ZHalf " << centDz;

  Volume cent2 = ns.addVolumeNS(Volume(name, solid, ns.material(centMat)));
  layer.placeVolume(cent2, 1, Position(0e0,0e0,centZ)); // copyNr=1
  LogDebug("TIBGeom") << cent2.name() 
      << " positioned in " << layer.name()
      << " at (0,0," << centZ << ") with no rotation";
  //
  ////// DOHM
  //
  // Preparing DOHM Carrier solid
  //
  name = idName + "DOHMCarrier";
  double dohmCarrierRin   = MFRingOutR - MFRingT;
  double dohmCarrierRout  = MFRingOutR;
  double dohmCarrierDz    = 0.5*(dohmPrimL+dohmtoMF);
  double dohmCarrierZ     = 0.5*layerL-2.*MFRingDz-dohmCarrierDz;

  solid = ns.addSolidNS(name,Tube(dohmCarrierRin, dohmCarrierRout, 
                                  dohmCarrierPhiOff, dohmCarrierDz, 
                                  180.*CLHEP::deg-2.*dohmCarrierPhiOff));
  LogDebug("TIBGeom") << solid.name() << " Tubs made of "
      << dohmCarrierMaterial << " from "
      << dohmCarrierPhiOff << " to " 
      << 180.*CLHEP::deg-dohmCarrierPhiOff << " with Rin "
      << dohmCarrierRin << " Rout " << MFRingOutR << " ZHalf " 
      << dohmCarrierDz;
  
  // Define FW and BW carrier logical volume and
  // place DOHM Primary and auxiliary modules inside it
  dphi = CLHEP::twopi/stringsUp;

  Rotation3D dohmRotation;
  double dohmR = 0.5*(dohmCarrierRin+dohmCarrierRout);

  for (int j = 0; j<4; j++) {
    vector<double> dohmList;
    Position tran;
    string rotstr;
    Rotation3D rotation;
    int dohmCarrierReplica=0;
    int placeDohm = 0;

    switch (j){
    case 0:
      name = idName + "DOHMCarrierFW";
      dohmList = dohmListFW;
      tran = Position(0., 0., dohmCarrierZ);
      rotstr = idName + "FwUp";
      rotation = Rotation3D();
      dohmCarrierReplica = 1;
      placeDohm=1;
      break;
    case 1:
      name = idName + "DOHMCarrierFW";
      dohmList = dohmListFW;
      tran = Position(0., 0., dohmCarrierZ);
      rotstr = idName + "FwDown";
      rotation = make_rotation3D(90.*CLHEP::deg, 180.*CLHEP::deg, 90.*CLHEP::deg,270.*CLHEP::deg, 0.,0.);
      dohmCarrierReplica = 2;
      placeDohm=0;
      break;
    case 2:
      name = idName + "DOHMCarrierBW";
      dohmList = dohmListBW;
      tran = Position(0., 0., -dohmCarrierZ);
      rotstr = idName + "BwUp";
      rotation = make_rotation3D(90.*CLHEP::deg, 180.*CLHEP::deg, 90.*CLHEP::deg, 90.*CLHEP::deg, 180.*CLHEP::deg, 0.);
      dohmCarrierReplica = 1;
      placeDohm=1;
      break;
    case 3:
      name = idName + "DOHMCarrierBW";
      dohmList = dohmListBW;
      tran = Position(0., 0., -dohmCarrierZ);
      rotstr = idName + "BwDown";
      rotation = make_rotation3D(90.*CLHEP::deg, 0., 90.*CLHEP::deg, 270.*CLHEP::deg, 180.*CLHEP::deg, 0.);
      dohmCarrierReplica = 2;
      placeDohm=0;
      break;
    }

    Volume dohmCarrier = ns.addVolumeNS(Volume(name,solid,ns.material(dohmCarrierMaterial)));
    int primReplica = 0;
    int auxReplica = 0;
#if 0
    for ( size_t i = 0; i < placeDohm*dohmList.size(); i++ )   {
      double phi   = (std::abs(dohmList[i])+0.5-1.)*dphi;
      double phix  = phi + 90*CLHEP::deg;
      double theta = 90*CLHEP::deg;
      double phiy  = phix + 90.*CLHEP::deg;
      dohmRotation = make_rotation3D(theta, phix, theta, phiy, 0., 0.);

      int    dohmReplica = 0;
      double dohmZ = 0.;
      Volume dohm;

      if(dohmList[i]<0.) {
        // Place a Auxiliary DOHM
        dohm  = ns.volume(dohmAuxName);
        dohmZ = dohmCarrierDz - 0.5*dohmAuxL - dohmtoMF;
        primReplica++;
        dohmReplica = primReplica;
      } else {
        // Place a Primary DOHM
        dohm = ns.volume(dohmPrimName);
        dohmZ = dohmCarrierDz - 0.5*dohmPrimL - dohmtoMF;
        auxReplica++;
        dohmReplica = auxReplica;
      }
      Position dohmTrasl(dohmR*cos(phi), dohmR*sin(phi), dohmZ);
      dohmCarrier.placeVolume(dohm,dohmReplica,Transform3D(dohmRotation,dohmTrasl));
      LogDebug("TIBGeom") << dohm.name() 
          << " replica " << dohmReplica << " positioned in " 
          << dohmCarrier.name() << " at " << dohmTrasl << " with "
          << dohmRotation;
    }
#else
    if ( placeDohm || primReplica || auxReplica || dohmR>0e0 )  {} // Avoid warnings
    LogWarn("TIBGeom") << "DOOHM placement sucks for Geant4. ERASED!";
#endif
    layer.placeVolume(dohmCarrier, dohmCarrierReplica, Transform3D(rotation,tran));// copyNr = dohmCarrierReplica
    LogDebug("TIBGeom") << "DDTIBLayerAlgo test "
        << dohmCarrier.name() << " positioned in " << mother
        << " replica " << dohmCarrierReplica << " at "
        << tran << " with " << rotation;
  }
  //
  ////// PILLARS
  for (int j = 0; j<4; j++) {    
    vector<double> pillarZ;
    vector<double> pillarPhi;
    double pillarDz=0, pillarDPhi=0, pillarRin=0, pillarRout=0;
    
    switch (j){
    case 0:
      name = idName + "FWIntPillar";
      pillarZ    = fwIntPillarZ;
      pillarPhi  = fwIntPillarPhi;
      pillarRin  = MFRingInR;
      pillarRout = MFRingInR + MFRingT;
      pillarDz   = fwIntPillarDz;
      pillarDPhi = fwIntPillarDPhi;
      break;
    case 1:
      name = idName + "BWIntPillar";
      pillarZ    = bwIntPillarZ;
      pillarPhi  = bwIntPillarPhi;
      pillarRin  = MFRingInR;
      pillarRout = MFRingInR + MFRingT;
      pillarDz   = bwIntPillarDz;
      pillarDPhi = bwIntPillarDPhi;
      break;
    case 2:
      name = idName + "FWExtPillar";
      pillarZ    = fwExtPillarZ;
      pillarPhi  = fwExtPillarPhi;
      pillarRin  = MFRingOutR - MFRingT;
      pillarRout = MFRingOutR;
      pillarDz   = fwExtPillarDz;
      pillarDPhi = fwExtPillarDPhi;
      break;
    case 3:
      name = idName + "BWExtPillar";
      pillarZ    = bwExtPillarZ;
      pillarPhi  = bwExtPillarPhi;
      pillarRin  = MFRingOutR - MFRingT;
      pillarRout = MFRingOutR;
      pillarDz   = bwExtPillarDz;
      pillarDPhi = bwExtPillarDPhi;
      break;
    }
    
    solid = ns.addSolidNS(name,Tube(pillarRin, pillarRout, pillarDz, -pillarDPhi, 2.*pillarDPhi));    
    Volume Pillar = ns.addVolumeNS(Volume(name,solid,ns.material(pillarMaterial)));
    LogDebug("TIBGeom") << solid.name() << " Tubs made of " << pillarMaterial << " from "
        << -pillarDPhi << " to " << pillarDPhi << " with Rin "
        << pillarRin << " Rout " << pillarRout << " ZHalf "  
        << pillarDz;
    Position   pillarTran;
    Rotation3D pillarRota;
    int pillarReplica = 0;
    for (unsigned int i=0; i<pillarZ.size(); i++) {
      if( pillarPhi[i]>0. ) {
        pillarTran = Position(0., 0., pillarZ[i]);
        pillarRota = make_rotation3D(90.*CLHEP::deg, pillarPhi[i], 90.*CLHEP::deg, 90.*CLHEP::deg+pillarPhi[i], 0., 0.);
        layer.placeVolume(Pillar,i,Transform3D(pillarRota,pillarTran)); // copyNr i
        LogDebug("TIBGeom") << Pillar.name() << " positioned in " 
            << mother << " at "
            << pillarTran << " with " << pillarRota 
            << " copy number " << pillarReplica;
        pillarReplica++;
      }
    }
  }
  return 1;
}