<commit_before>/*
* Copyright (C) 2007-2013 German Aerospace Center (DLR/SC)
*
* Created: 2013-12-12 Tobias Stollenwerk <Tobias.Stollenwerk@dlr.de>
* Changed: $Id$
*
* Version: $Revision$
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file
* @brief  Implementation of CPACS wing profile as a point list.
*/

#include <iostream>
#include <sstream>
#include <vector>

#include "CTiglError.h"
#include "CTiglLogging.h"
#include "math.h"

#include "gp_Pnt2d.hxx"
#include "gp_Vec2d.hxx"
#include "gp_Dir2d.hxx"
#include "gp_Pln.hxx"
#include "Bnd_Box.hxx"
#include "Geom2d_Line.hxx"
#include "Geom2d_TrimmedCurve.hxx"
#include "TopoDS.hxx"
#include "TopExp_Explorer.hxx"
#include "TopAbs_ShapeEnum.hxx"
#include "TopoDS_Edge.hxx"
#include "GCE2d_MakeSegment.hxx"
#include "BRep_Tool.hxx"
#include "BRepAdaptor_CompCurve.hxx"
#include "Geom2dAPI_InterCurveCurve.hxx"
#include "GeomAPI_ProjectPointOnCurve.hxx"
#include "GeomAPI.hxx"
#include "gce_MakeDir.hxx"
#include "gce_MakePln.hxx"
#include "BRepTools_WireExplorer.hxx"
#include "BRepBuilderAPI_MakeEdge.hxx"
#include "BRepBuilderAPI_MakeWire.hxx"
#include "BRepBndLib.hxx"
#include "ShapeFix_Wire.hxx"
#include "CTiglInterpolateBsplineWire.h"
#include "CTiglInterpolateLinearWire.h"

#include "ITiglWingProfileAlgo.h"
#include "CCPACSWingProfilePointList.h"

namespace tigl
{

    // Constructor
    CCPACSWingProfilePointList::CCPACSWingProfilePointList(const std::string& path)
    {
        ProfileDataXPath=path;
        profileWireAlgo = WireAlgoPointer(new CTiglInterpolateBsplineWire);
    }

    // Destructor
    CCPACSWingProfilePointList::~CCPACSWingProfilePointList(void)
    {
        delete profileWireAlgo;
    }

    // Cleanup routine
    void CCPACSWingProfilePointList::Cleanup(void)
    {
        for (CCPACSCoordinateContainer::size_type i = 0; i < coordinates.size(); i++)
        {
            delete coordinates[i];
        }
        coordinates.clear();
    }

    // Read wing profile file
    void CCPACSWingProfilePointList::ReadCPACS(TixiDocumentHandle tixiHandle)
    {
        try
        {
            /* Get point count */
            int   pointCount;
            if (tixiGetNamedChildrenCount(tixiHandle, ProfileDataXPath.c_str(), "point", &pointCount) != SUCCESS) {
                throw CTiglError("Error: tixiGetNamedChildrenCount failed in CCPACSWingProfilePointList::ReadCPACS", TIGL_XML_ERROR);
            }

            if (pointCount > 2)
            {
                // Loop over all points
                for (int i = 1; i <= pointCount; i++)
                {
                    CTiglPoint* point = new CTiglPoint(0.0, 0.0, 0.0);
                    coordinates.push_back(point);

                    std::ostringstream xpath;
                    xpath << ProfileDataXPath.c_str() << "/point[" << i << "]";
                    std::string x = xpath.str();
                    char * ptrPathChar = const_cast<char*>(x.c_str());

                    if (tixiGetPoint(tixiHandle, ptrPathChar, &(point->x), &(point->y), &(point->z)) != SUCCESS) {
                        throw CTiglError("Error: XML error while reading <point/> in CCPACSWingProfilePointList::ReadCPACS", TIGL_XML_ERROR);
                    }
                }
            }
            else // read in vector based point list
            {
                std::string xXpath = ProfileDataXPath +"/x";
                std::string yXpath = ProfileDataXPath +"/y";
                std::string zXpath = ProfileDataXPath +"/z";

                // check the number of elements in all three vectors. It has to be the same, otherwise cancel
                int countX;
                int countY;
                int countZ;
                if (tixiGetVectorSize(tixiHandle, xXpath.c_str(), &countX) != SUCCESS){
                    throw CTiglError("Error: XML error while reading point vector <x> in CCPACSWingProfilePointList::ReadCPACS", TIGL_XML_ERROR);
                }
                if (tixiGetVectorSize(tixiHandle, yXpath.c_str(), &countY) != SUCCESS){
                    throw CTiglError("Error: XML error while reading point vector <y> in CCPACSWingProfilePointList::ReadCPACS", TIGL_XML_ERROR);
                }
                if (tixiGetVectorSize(tixiHandle, zXpath.c_str(), &countZ) != SUCCESS){
                    throw CTiglError("Error: XML error while reading point vector <z> in CCPACSWingProfilePointList::ReadCPACS", TIGL_XML_ERROR);
                }

                if (countX != countY || countX != countZ || countY != countZ) {
                    throw CTiglError("Error: Vector size for profile points are not eqal in CCPACSWingProfilePointList::ReadCPACS", TIGL_XML_ERROR);
                }

                // read in vectors, vectors are allocated and freed by tixi
                double *xCoordinates = NULL;
                double *yCoordinates = NULL;
                double *zCoordinates = NULL;

                if (tixiGetFloatVector(tixiHandle, xXpath.c_str(), &xCoordinates, countX) != SUCCESS) {
                    throw CTiglError("Error: XML error while reading point vector <x> in CCPACSWingProfilePointList::ReadCPACS", TIGL_XML_ERROR);
                }
                if (tixiGetFloatVector(tixiHandle, yXpath.c_str(), &yCoordinates, countY) != SUCCESS) {
                    throw CTiglError("Error: XML error while reading point vector <y> in CCPACSWingProfilePointList::ReadCPACS", TIGL_XML_ERROR);
                }
                if (tixiGetFloatVector(tixiHandle, zXpath.c_str(), &zCoordinates, countZ) != SUCCESS) {
                    throw CTiglError("Error: XML error while reading point vector <z> in CCPACSWingProfilePointList::ReadCPACS", TIGL_XML_ERROR);
                }

                // Loop over all points in the vector
                for (int i = 0; i < countX; i++)
                {
                    CTiglPoint* point = new CTiglPoint(xCoordinates[i], yCoordinates[i], zCoordinates[i]);
                    coordinates.push_back(point);
                }
            }

        }
        catch (...)
        {
            throw;
        }
    }

    // Builds the wing profile wire. The returned wire is already transformed by the
    // wing profile element transformation.
    void CCPACSWingProfilePointList::BuildWires()
    {
        ITiglWireAlgorithm::CPointContainer points;
        for (CCPACSCoordinateContainer::size_type i = 0; i < coordinates.size(); i++)
            points.push_back(coordinates[i]->Get_gp_Pnt());

        // Build wires from wing profile points.
        const ITiglWireAlgorithm& wireBuilder = *profileWireAlgo;

        // CCPACSWingSegment::makeSurfaces cannot handle currently
        // wire with multiple edges. Thus we get problems if we have
        // a linear interpolated wire consting of many edges.
        if(dynamic_cast<const CTiglInterpolateLinearWire*>(&wireBuilder)){
            LOG(ERROR) << "Linear Wing Profiles are currently not supported" << endl;
            throw CTiglError("Linear Wing Profiles are currently not supported",TIGL_ERROR);
        }

        TopoDS_Wire tempWireClosed   = wireBuilder.BuildWire(points, true);
        if (tempWireClosed.IsNull() == Standard_True)
            throw CTiglError("Error: TopoDS_Wire is null in CCPACSWingProfilePointList::BuildWire", TIGL_ERROR);

        //@todo: do we really want to remove all y information? this has to be a bug
        // Apply wing profile transformation to wires
        CTiglTransformation transformation;
        transformation.AddProjectionOnXZPlane();

        TopoDS_Shape tempShapeClosed   = transformation.Transform(tempWireClosed);

        // Cast shapes to wires, see OpenCascade documentation
        if (tempShapeClosed.ShapeType() != TopAbs_WIRE)
            throw CTiglError("Error: Wrong shape type in CCPACSWingProfilePointList::BuildWire", TIGL_ERROR);

        wireClosed   = TopoDS::Wire(tempShapeClosed);

        BuildLETEPoints();

        // Create upper and lower wires
        // Get BSpline curve
        Handle_Geom_BSplineCurve curve = BRepAdaptor_CompCurve(wireClosed).BSpline();
        // Get Leading edge parameter on curve
        double lep_par = GeomAPI_ProjectPointOnCurve(lePoint, curve).LowerDistanceParameter();

        // upper and lower edges
        TopoDS_Edge edge1, edge2;
        edge1 = BRepBuilderAPI_MakeEdge(curve,curve->FirstParameter(), lep_par);
        edge2 = BRepBuilderAPI_MakeEdge(curve,lep_par, curve->LastParameter());

        // Get maximal z-values of both edges via bounding box
        Bnd_Box boundingBox1;
        Bnd_Box boundingBox2;
        Standard_Real xmin, ymin, zmin, xmax, ymax, zmax1, zmax2;
        BRepBndLib::Add(edge1, boundingBox1);
        BRepBndLib::Add(edge2, boundingBox2);
        boundingBox1.Get(xmin, ymin, zmin, xmax, ymax, zmax1);
        boundingBox2.Get(xmin, ymin, zmin, xmax, ymax, zmax2);

        // Trailing edge points
        gp_Pnt te_up, te_down;
        // Find out which edge is on top and asign upper and lower edge
        TopoDS_Edge lower_edge, upper_edge;
        if(zmax2<zmax1)
        {
            //wire goes from top to bottom
            upper_edge = edge1;
            lower_edge = edge2;
            te_up = curve->StartPoint();
            te_down = curve->EndPoint();
        }
        else {
            //wire goes from bottom to top
            lower_edge = edge1;
            upper_edge = edge2;
            te_up = curve->EndPoint();
            te_down = curve->StartPoint();
        }
        // Wire builder
        BRepBuilderAPI_MakeWire upperWireBuilder, lowerWireBuilder;

        //check if we have to close upper and lower wing shells
        if(te_up.Distance(te_down) > Precision::Confusion())
        {
            lowerWireBuilder.Add(BRepBuilderAPI_MakeEdge(te_up,te_down));
        }

        upperWireBuilder.Add(upper_edge);
        lowerWireBuilder.Add(lower_edge);

        upperWire = upperWireBuilder.Wire();
        lowerWire = lowerWireBuilder.Wire();
    }

    // Builds leading and trailing edge points of the wing profile wire.
    void CCPACSWingProfilePointList::BuildLETEPoints(void)
    {
        // compute TE point
        gp_Pnt firstPnt = coordinates[0]->Get_gp_Pnt();
        gp_Pnt lastPnt  = coordinates[coordinates.size() - 1]->Get_gp_Pnt();
        if( fabs(firstPnt.X() - lastPnt.X()) < Precision::Confusion()){
            double x = (firstPnt.X() + lastPnt.X())/2.;
            double y = (firstPnt.Y() + lastPnt.Y())/2.;
            double z = (firstPnt.Z() + lastPnt.Z())/2.;
            tePoint = gp_Pnt(x,y,z);
        }
        else if(firstPnt.X() > lastPnt.X()) {
            tePoint = firstPnt;
        }
        else {
            tePoint = lastPnt;
        }

        // find the point with the max dist to TE point
        lePoint = tePoint;
        CCPACSCoordinateContainer::iterator pit = coordinates.begin();
        for(; pit != coordinates.end(); ++pit) {
            gp_Pnt point = (*pit)->Get_gp_Pnt();
            if(tePoint.Distance(point) > tePoint.Distance(lePoint)) {
                lePoint = point;
            }
        }
        // project into x-z plane
        lePoint.SetY(0.);
        tePoint.SetY(0.);
    }
    // Returns the profile points as read from TIXI.
    std::vector<CTiglPoint*> CCPACSWingProfilePointList::GetSamplePoints() const
    {
        std::vector<CTiglPoint*> newPointVector;
        for (CCPACSCoordinateContainer::size_type i = 0; i < coordinates.size(); i++)
        {
            gp_Pnt pnt = coordinates[i]->Get_gp_Pnt();
            //@TODO: i dont't see why we should transform here
            //pnt = TransformPoint(pnt);
            newPointVector.push_back(new CTiglPoint(pnt.X(), pnt.Y(), pnt.Z()));
        }
        return newPointVector;
    }

    // get profiles CPACS XML path
    const std::string & CCPACSWingProfilePointList::GetProfileDataXPath()
    {
        return ProfileDataXPath;
    }

    // get forced closed wing profile wire
    const TopoDS_Wire & CCPACSWingProfilePointList::GetWireClosed()
    {
        return wireClosed;
    }

    // get upper wing profile wire
    const TopoDS_Wire & CCPACSWingProfilePointList::GetUpperWire()
    {
        return upperWire;
    }

    // get lower wing profile wire
    const TopoDS_Wire & CCPACSWingProfilePointList::GetLowerWire()
    {
        return lowerWire;
    }

    // get leading edge point();
    const gp_Pnt & CCPACSWingProfilePointList::GetLEPoint()
    {
        return lePoint;
    }

    // get trailing edge point();
    const gp_Pnt & CCPACSWingProfilePointList::GetTEPoint()
    {
        return tePoint;
    }

} // end namespace tigl
<commit_msg>Code reduction in CCPACSWingProfilePointList<commit_after>/*
* Copyright (C) 2007-2013 German Aerospace Center (DLR/SC)
*
* Created: 2013-12-12 Tobias Stollenwerk <Tobias.Stollenwerk@dlr.de>
* Changed: $Id$
*
* Version: $Revision$
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file
* @brief  Implementation of CPACS wing profile as a point list.
*/

#include <iostream>
#include <sstream>
#include <vector>

#include "CTiglError.h"
#include "CTiglLogging.h"
#include "math.h"

#include "gp_Pnt2d.hxx"
#include "gp_Vec2d.hxx"
#include "gp_Dir2d.hxx"
#include "gp_Pln.hxx"
#include "Bnd_Box.hxx"
#include "Geom2d_Line.hxx"
#include "Geom2d_TrimmedCurve.hxx"
#include "TopoDS.hxx"
#include "TopExp_Explorer.hxx"
#include "TopAbs_ShapeEnum.hxx"
#include "TopoDS_Edge.hxx"
#include "GCE2d_MakeSegment.hxx"
#include "BRep_Tool.hxx"
#include "BRepAdaptor_CompCurve.hxx"
#include "Geom2dAPI_InterCurveCurve.hxx"
#include "GeomAPI_ProjectPointOnCurve.hxx"
#include "GeomAPI.hxx"
#include "gce_MakeDir.hxx"
#include "gce_MakePln.hxx"
#include "BRepTools_WireExplorer.hxx"
#include "BRepBuilderAPI_MakeEdge.hxx"
#include "BRepBuilderAPI_MakeWire.hxx"
#include "BRepBndLib.hxx"
#include "ShapeFix_Wire.hxx"
#include "CTiglInterpolateBsplineWire.h"
#include "CTiglInterpolateLinearWire.h"

#include "ITiglWingProfileAlgo.h"
#include "CCPACSWingProfilePointList.h"

namespace tigl
{

    // Constructor
    CCPACSWingProfilePointList::CCPACSWingProfilePointList(const std::string& path)
    {
        ProfileDataXPath=path;
        profileWireAlgo = WireAlgoPointer(new CTiglInterpolateBsplineWire);
    }

    // Destructor
    CCPACSWingProfilePointList::~CCPACSWingProfilePointList(void)
    {
        delete profileWireAlgo;
    }

    // Cleanup routine
    void CCPACSWingProfilePointList::Cleanup(void)
    {
        for (CCPACSCoordinateContainer::size_type i = 0; i < coordinates.size(); i++)
        {
            delete coordinates[i];
        }
        coordinates.clear();
    }

    // Read wing profile file
    void CCPACSWingProfilePointList::ReadCPACS(TixiDocumentHandle tixiHandle)
    {
        try
        {
            /* Get point count */
            int   pointCount;
            if (tixiGetNamedChildrenCount(tixiHandle, ProfileDataXPath.c_str(), "point", &pointCount) != SUCCESS) {
                throw CTiglError("Error: tixiGetNamedChildrenCount failed in CCPACSWingProfilePointList::ReadCPACS", TIGL_XML_ERROR);
            }

            if (pointCount > 2)
            {
                // Loop over all points
                for (int i = 1; i <= pointCount; i++)
                {
                    CTiglPoint* point = new CTiglPoint(0.0, 0.0, 0.0);
                    coordinates.push_back(point);

                    std::ostringstream xpath;
                    xpath << ProfileDataXPath.c_str() << "/point[" << i << "]";
                    std::string x = xpath.str();
                    char * ptrPathChar = const_cast<char*>(x.c_str());

                    if (tixiGetPoint(tixiHandle, ptrPathChar, &(point->x), &(point->y), &(point->z)) != SUCCESS) {
                        throw CTiglError("Error: XML error while reading <point/> in CCPACSWingProfilePointList::ReadCPACS", TIGL_XML_ERROR);
                    }
                }
            }
            else // read in vector based point list
            {
                std::string xXpath = ProfileDataXPath +"/x";
                std::string yXpath = ProfileDataXPath +"/y";
                std::string zXpath = ProfileDataXPath +"/z";

                // check the number of elements in all three vectors. It has to be the same, otherwise cancel
                int countX;
                int countY;
                int countZ;
                if (tixiGetVectorSize(tixiHandle, xXpath.c_str(), &countX) != SUCCESS){
                    throw CTiglError("Error: XML error while reading point vector <x> in CCPACSWingProfilePointList::ReadCPACS", TIGL_XML_ERROR);
                }
                if (tixiGetVectorSize(tixiHandle, yXpath.c_str(), &countY) != SUCCESS){
                    throw CTiglError("Error: XML error while reading point vector <y> in CCPACSWingProfilePointList::ReadCPACS", TIGL_XML_ERROR);
                }
                if (tixiGetVectorSize(tixiHandle, zXpath.c_str(), &countZ) != SUCCESS){
                    throw CTiglError("Error: XML error while reading point vector <z> in CCPACSWingProfilePointList::ReadCPACS", TIGL_XML_ERROR);
                }

                if (countX != countY || countX != countZ || countY != countZ) {
                    throw CTiglError("Error: Vector size for profile points are not eqal in CCPACSWingProfilePointList::ReadCPACS", TIGL_XML_ERROR);
                }

                // read in vectors, vectors are allocated and freed by tixi
                double *xCoordinates = NULL;
                double *yCoordinates = NULL;
                double *zCoordinates = NULL;

                if (tixiGetFloatVector(tixiHandle, xXpath.c_str(), &xCoordinates, countX) != SUCCESS) {
                    throw CTiglError("Error: XML error while reading point vector <x> in CCPACSWingProfilePointList::ReadCPACS", TIGL_XML_ERROR);
                }
                if (tixiGetFloatVector(tixiHandle, yXpath.c_str(), &yCoordinates, countY) != SUCCESS) {
                    throw CTiglError("Error: XML error while reading point vector <y> in CCPACSWingProfilePointList::ReadCPACS", TIGL_XML_ERROR);
                }
                if (tixiGetFloatVector(tixiHandle, zXpath.c_str(), &zCoordinates, countZ) != SUCCESS) {
                    throw CTiglError("Error: XML error while reading point vector <z> in CCPACSWingProfilePointList::ReadCPACS", TIGL_XML_ERROR);
                }

                // Loop over all points in the vector
                for (int i = 0; i < countX; i++)
                {
                    CTiglPoint* point = new CTiglPoint(xCoordinates[i], yCoordinates[i], zCoordinates[i]);
                    coordinates.push_back(point);
                }
            }

        }
        catch (...)
        {
            throw;
        }
    }

    // Builds the wing profile wire. The returned wire is already transformed by the
    // wing profile element transformation.
    void CCPACSWingProfilePointList::BuildWires()
    {
        ITiglWireAlgorithm::CPointContainer points;
        for (CCPACSCoordinateContainer::size_type i = 0; i < coordinates.size(); i++)
            points.push_back(coordinates[i]->Get_gp_Pnt());

        // Build wires from wing profile points.
        const ITiglWireAlgorithm& wireBuilder = *profileWireAlgo;

        // CCPACSWingSegment::makeSurfaces cannot handle currently
        // wire with multiple edges. Thus we get problems if we have
        // a linear interpolated wire consting of many edges.
        if(dynamic_cast<const CTiglInterpolateLinearWire*>(&wireBuilder)){
            LOG(ERROR) << "Linear Wing Profiles are currently not supported" << endl;
            throw CTiglError("Linear Wing Profiles are currently not supported",TIGL_ERROR);
        }

        TopoDS_Wire tempWireClosed   = wireBuilder.BuildWire(points, true);
        if (tempWireClosed.IsNull() == Standard_True)
            throw CTiglError("Error: TopoDS_Wire is null in CCPACSWingProfilePointList::BuildWire", TIGL_ERROR);

        //@todo: do we really want to remove all y information? this has to be a bug
        // Apply wing profile transformation to wires
        CTiglTransformation transformation;
        transformation.AddProjectionOnXZPlane();

        TopoDS_Shape tempShapeClosed   = transformation.Transform(tempWireClosed);

        // Cast shapes to wires, see OpenCascade documentation
        if (tempShapeClosed.ShapeType() != TopAbs_WIRE)
            throw CTiglError("Error: Wrong shape type in CCPACSWingProfilePointList::BuildWire", TIGL_ERROR);

        wireClosed   = TopoDS::Wire(tempShapeClosed);

        BuildLETEPoints();

        // Create upper and lower wires
        // Get BSpline curve
        Handle_Geom_BSplineCurve curve = BRepAdaptor_CompCurve(wireClosed).BSpline();
        // Get Leading edge parameter on curve
        double lep_par = GeomAPI_ProjectPointOnCurve(lePoint, curve).LowerDistanceParameter();

        // upper and lower edges
        TopoDS_Edge edge1, edge2;
        edge1 = BRepBuilderAPI_MakeEdge(curve,curve->FirstParameter(), lep_par);
        edge2 = BRepBuilderAPI_MakeEdge(curve,lep_par, curve->LastParameter());

        // Get maximal z-values of both edges via bounding box
        Bnd_Box boundingBox1;
        Bnd_Box boundingBox2;
        Standard_Real xmin, ymin, zmin, xmax, ymax, zmax1, zmax2;
        BRepBndLib::Add(edge1, boundingBox1);
        BRepBndLib::Add(edge2, boundingBox2);
        boundingBox1.Get(xmin, ymin, zmin, xmax, ymax, zmax1);
        boundingBox2.Get(xmin, ymin, zmin, xmax, ymax, zmax2);

        // Trailing edge points
        gp_Pnt te_up, te_down;
        // Find out which edge is on top and asign upper and lower edge
        TopoDS_Edge lower_edge, upper_edge;
        if(zmax2<zmax1)
        {
            //wire goes from top to bottom
            upper_edge = edge1;
            lower_edge = edge2;
            te_up = curve->StartPoint();
            te_down = curve->EndPoint();
        }
        else {
            //wire goes from bottom to top
            lower_edge = edge1;
            upper_edge = edge2;
            te_up = curve->EndPoint();
            te_down = curve->StartPoint();
        }
        // Wire builder
        BRepBuilderAPI_MakeWire upperWireBuilder, lowerWireBuilder;

        //check if we have to close upper and lower wing shells
        if(te_up.Distance(te_down) > Precision::Confusion())
        {
            lowerWireBuilder.Add(BRepBuilderAPI_MakeEdge(te_up,te_down));
        }

        upperWireBuilder.Add(upper_edge);
        lowerWireBuilder.Add(lower_edge);

        upperWire = upperWireBuilder.Wire();
        lowerWire = lowerWireBuilder.Wire();
    }

    // Builds leading and trailing edge points of the wing profile wire.
    void CCPACSWingProfilePointList::BuildLETEPoints(void)
    {
        // compute TE point
        gp_Pnt firstPnt = coordinates[0]->Get_gp_Pnt();
        gp_Pnt lastPnt  = coordinates[coordinates.size() - 1]->Get_gp_Pnt();
        if( fabs(firstPnt.X() - lastPnt.X()) < Precision::Confusion()){
            double x = (firstPnt.X() + lastPnt.X())/2.;
            double y = (firstPnt.Y() + lastPnt.Y())/2.;
            double z = (firstPnt.Z() + lastPnt.Z())/2.;
            tePoint = gp_Pnt(x,y,z);
        }
        else if(firstPnt.X() > lastPnt.X()) {
            tePoint = firstPnt;
        }
        else {
            tePoint = lastPnt;
        }

        // find the point with the max dist to TE point
        lePoint = tePoint;
        CCPACSCoordinateContainer::iterator pit = coordinates.begin();
        for(; pit != coordinates.end(); ++pit) {
            gp_Pnt point = (*pit)->Get_gp_Pnt();
            if(tePoint.Distance(point) > tePoint.Distance(lePoint)) {
                lePoint = point;
            }
        }
        // project into x-z plane
        lePoint.SetY(0.);
        tePoint.SetY(0.);
    }
    // Returns the profile points as read from TIXI.
    std::vector<CTiglPoint*> CCPACSWingProfilePointList::GetSamplePoints() const
    {
        return coordinates;
    }

    // get profiles CPACS XML path
    const std::string & CCPACSWingProfilePointList::GetProfileDataXPath()
    {
        return ProfileDataXPath;
    }

    // get forced closed wing profile wire
    const TopoDS_Wire & CCPACSWingProfilePointList::GetWireClosed()
    {
        return wireClosed;
    }

    // get upper wing profile wire
    const TopoDS_Wire & CCPACSWingProfilePointList::GetUpperWire()
    {
        return upperWire;
    }

    // get lower wing profile wire
    const TopoDS_Wire & CCPACSWingProfilePointList::GetLowerWire()
    {
        return lowerWire;
    }

    // get leading edge point();
    const gp_Pnt & CCPACSWingProfilePointList::GetLEPoint()
    {
        return lePoint;
    }

    // get trailing edge point();
    const gp_Pnt & CCPACSWingProfilePointList::GetTEPoint()
    {
        return tePoint;
    }

} // end namespace tigl
<|endoftext|>


<commit_before>#pragma once

#include <cassert>
#include <iostream>
#include <string>

#include "fixfmt/math.hh"

//------------------------------------------------------------------------------

namespace fixfmt {

using std::string;

constexpr char const* ELLIPSIS = "\u2026";

/**
 * Advances an iterator on a UTF-8 string by one code point.
 */
inline void
next_utf8(string::const_iterator& i)
{
  unsigned char c = *i++;
  if ((c & 0xc0) == 0xc0) {
    // It's multibyte.  The number of bytes is the number of MSB's before
    // the first zero.
    // FIXME: Improve this.
    ++i;
    if ((c & 0xe0) == 0xe0) {
      ++i;
      if ((c & 0xf0) == 0xf0) {
        ++i;
        if ((c & 0xf8) == 0xf8) {
          ++i;
          if ((c & 0xfc) == 0xfc)
            ++i;
        }
      }
    }
  }
}

/**
 * Returns the number of code points in a UTF-8-encoded string.
 */
inline size_t
utf8_length(string const& str)
{
  size_t length = 0;
  // FIXME: Problem if the last code point is malformed.
  for (auto i = str.begin(); i != str.end(); next_utf8(i))
    ++length;
  return length;
}

constexpr char ANSI_ESCAPE = '\x1b';

inline bool
within(unsigned char min, unsigned char val, unsigned char max)
{
  return min <= val && val <= max;
}

/**
 * Advances an iterator past an ANSI escape sequence, if it is positioned at
 * one.
 */
inline bool
skip_ansi_escape(string::const_iterator& i, string::const_iterator const& end)
{
  assert(i != end);
  if (*i == ANSI_ESCAPE) {
    ++i;
    if (i != end && *i++ == '[')
      // Got CSI.  Read until we pass a final byte.
      while (i != end && !within(64, *i++, 126))
        ;
    else
      // Assume single-character escape.
      ;
    return true;
  }
  else
    return false;
}

/**
 * Returns the number of code points in a UTF-8-encoded string, skipping
 * escape sequences.
 */
inline size_t
string_length(string const& str)
{
  size_t length = 0;
  auto const& end = str.end();
  // FIXME: Problem if the last code point is malformed.

  auto i = str.begin();
  // Count characters.
  while (i != end) {
    if (skip_ansi_escape(i, end))
      ;
    else {
      ++length;
      next_utf8(i);
    }
  }
  return length;
}

/**
 * Concatenates copies of `str` up to `length`.  If `length` is not divisible
 * by the length of `str`, the last copy is partial.
 */
inline string
fill(
  string const& str,
  size_t const length)
{
  size_t const str_len = string_length(str);
  assert(str_len > 0);
  if (str.length() == 1)
    return string(length, str[0]);
  else {
    string result;
    result.reserve(length);
    // Concatenate whole copies.
    size_t l = length;
    while (l >= str_len) {
      result += str;
      l -= str_len;
    }
    if (l > 0) {
      // Concatenate a partial copy.
      auto i = str.begin();
      for (; l > 0; --l)
        next_utf8(i);
      result.append(str.begin(), i);
    }
    assert(string_length(result) == length);
    return result;
  }
}

inline string
pad(
  string const& str,
  size_t const length,
  string const& pad=" ",
  bool const left=false)
{
  size_t const str_len = string_length(str);
  if (str_len < length) {
    string const padding = fill(pad, length - str_len);
    string const result = left ? padding + str : str + padding;
    assert(string_length(result) == length);
    return result;
  }
  else
    return str;
}

inline string
elide(
  string const& str,
  size_t const max_length,
  string const& ellipsis=ELLIPSIS,
  float const position=1.0)
{
  size_t const ellipsis_len = string_length(ellipsis);
  assert(max_length >= ellipsis_len);
  assert(0 <= position);
  assert(position <= 1);

  size_t const length = string_length(str);
  if (length <= max_length)
    return str;
  else {
    size_t const keep   = max_length - ellipsis_len;
    size_t const nleft  = (size_t) round(position * keep);
    size_t const nright = keep - nleft;
    string elided;
    if (nleft > 0)
      elided += str.substr(0, nleft);
    elided += ellipsis;
    if (nright > 0)
      elided += str.substr(length - nright);
    assert(string_length(elided) == max_length);
    return elided;
  }
}

inline string
palide(
  string const& str,
  size_t const length,
  string const& ellipsis=ELLIPSIS,
  string const& pad=" ",
  float const position=1.0,
  bool const left=false)
{
  return fixfmt::pad(elide(str, length, ellipsis, position), length, pad, left);
}

}  // namespace fixfmt
<commit_msg>Cleanups.<commit_after>#pragma once

#include <cassert>
#include <iostream>
#include <string>

#include "fixfmt/math.hh"

//------------------------------------------------------------------------------

namespace fixfmt {

using std::string;

constexpr char const* ELLIPSIS = "\u2026";

/**
 * Advances an iterator on a UTF-8 string by one code point.
 */
// FIXME: Take an end parameter.
inline void
next_utf8(string::const_iterator& i)
{
  unsigned char c = *i++;
  if ((c & 0xc0) == 0xc0) {
    // It's multibyte.  The number of bytes is the number of MSB's before
    // the first zero.
    // FIXME: Improve this.
    ++i;
    if ((c & 0xe0) == 0xe0) {
      ++i;
      if ((c & 0xf0) == 0xf0) {
        ++i;
        if ((c & 0xf8) == 0xf8) {
          ++i;
          if ((c & 0xfc) == 0xfc)
            ++i;
        }
      }
    }
  }
}

/**
 * Returns the number of code points in a UTF-8-encoded string.
 */
inline size_t
utf8_length(string const& str)
{
  size_t length = 0;
  // FIXME: Problem if the last code point is malformed.
  for (auto i = str.begin(); i != str.end(); next_utf8(i))
    ++length;
  return length;
}

// FIXME: Elsewhere.

constexpr char ANSI_ESCAPE = '\x1b';

inline bool
within(unsigned char min, unsigned char val, unsigned char max)
{
  return min <= val && val <= max;
}

/**
 * Advances an iterator past an ANSI escape sequence, if it is positioned at
 * one.
 */
inline bool
skip_ansi_escape(string::const_iterator& i, string::const_iterator const& end)
{
  assert(i != end);
  if (*i == ANSI_ESCAPE) {
    ++i;
    if (i != end && *i++ == '[')
      // Got CSI.  Read until we pass a final byte.
      while (i != end && !within(64, *i++, 126))
        ;
    else
      // Assume single-character escape.
      ;
    return true;
  }
  else
    return false;
}

/**
 * Returns the number of code points in a UTF-8-encoded string, skipping
 * escape sequences.
 */
inline size_t
string_length(string const& str)
{
  size_t length = 0;
  auto const& end = str.end();
  // FIXME: Problem if the last code point is malformed.
  // Count characters.
  for (auto i = str.begin(); i != end; )
    if (skip_ansi_escape(i, end))
      ;
    else {
      ++length;
      next_utf8(i);
    }
  return length;
}

/**
 * Concatenates copies of `str` up to `length`.  If `length` is not divisible
 * by the length of `str`, the last copy is partial.
 */
inline string
fill(
  string const& str,
  size_t const length)
{
  size_t const str_len = string_length(str);
  assert(str_len > 0);
  if (str.length() == 1)
    return string(length, str[0]);
  else {
    string result;
    result.reserve(length);
    // Concatenate whole copies.
    size_t l = length;
    while (l >= str_len) {
      result += str;
      l -= str_len;
    }
    if (l > 0) {
      // Concatenate a partial copy.
      auto i = str.begin();
      for (; l > 0; --l)
        next_utf8(i);
      result.append(str.begin(), i);
    }
    assert(string_length(result) == length);
    return result;
  }
}

inline string
pad(
  string const& str,
  size_t const length,
  string const& pad=" ",
  bool const left=false)
{
  size_t const str_len = string_length(str);
  if (str_len < length) {
    string const padding = fill(pad, length - str_len);
    string const result = left ? padding + str : str + padding;
    assert(string_length(result) == length);
    return result;
  }
  else
    return str;
}

inline string
elide(
  string const& str,
  size_t const max_length,
  string const& ellipsis=ELLIPSIS,
  float const position=1.0)
{
  size_t const ellipsis_len = string_length(ellipsis);
  assert(max_length >= ellipsis_len);
  assert(0 <= position);
  assert(position <= 1);

  size_t const length = string_length(str);
  if (length <= max_length)
    return str;
  else {
    size_t const keep   = max_length - ellipsis_len;
    size_t const nleft  = (size_t) round(position * keep);
    size_t const nright = keep - nleft;
    string elided;
    if (nleft > 0)
      elided += str.substr(0, nleft);
    elided += ellipsis;
    if (nright > 0)
      elided += str.substr(length - nright);
    assert(string_length(elided) == max_length);
    return elided;
  }
}

inline string
palide(
  string const& str,
  size_t const length,
  string const& ellipsis=ELLIPSIS,
  string const& pad=" ",
  float const position=1.0,
  bool const left=false)
{
  return fixfmt::pad(elide(str, length, ellipsis, position), length, pad, left);
}

}  // namespace fixfmt
<|endoftext|>


<commit_before>// Copyright (c) 2014 Baidu, Inc.G
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Authors: Lei He (helei@qiyi.com)

#include <cmath>
#include <gflags/gflags.h>
#include "brpc/circuit_breaker.h"

namespace brpc {

DEFINE_int32(circuit_breaker_short_window_size, 100,
    "Short window sample size.");
DEFINE_int32(circuit_breaker_long_window_size, 1000,
    "Long window sample size.");
DEFINE_int32(circuit_breaker_short_window_error_percent, 5,
    "The maximum error rate allowed by the short window, ranging from 0-99.");
DEFINE_int32(circuit_breaker_long_window_error_percent, 3,
    "The maximum error rate allowed by the long window, ranging from 0-99.");
DEFINE_int32(circuit_breaker_min_error_cost_us, 100,
    "The minimum error_cost, when the ema of error cost is less than this "
    "value, it will be set to zero.");
DEFINE_int32(circuit_breaker_max_failed_latency_mutilple, 2,
    "The maximum multiple of the latency of the failed request relative to "
    "the average latency of the success requests.");

namespace {
// EPSILON is used to generate the smoothing coefficient when calculating EMA.
// The larger the EPSILON, the larger the smoothing coefficient, which means
// that the proportion of early data is larger.
// smooth = pow(EPSILON, 1 / window_size),
// eg: when window_size = 100,
// EPSILON = 0.1, smooth = 0.9772
// EPSILON = 0.3, smooth = 0.9880
// when window_size = 1000,
// EPSILON = 0.1, smooth = 0.9977
// EPSILON = 0.3, smooth = 0.9987
const double EPSILON = 0.1;
}  // namepace

CircuitBreaker::EmaErrorRecorder::EmaErrorRecorder(int window_size,
                                                   int max_error_percent)
    : _window_size(window_size)
    , _max_error_percent(max_error_percent)
    , _smooth(std::pow(EPSILON, 1.0/window_size))
    , _sample_count(0)
    , _ema_error_cost(0)
    , _ema_latency(0)
    , _broken(false) {
}

bool CircuitBreaker::EmaErrorRecorder::OnCallEnd(int error_code,
                                                 int64_t latency) {
    if (_broken.load(butil::memory_order_relaxed)) {
        return false;
    }

    int64_t ema_latency = 0;
    bool healthy = false;
    if (error_code == 0) {
        ema_latency = UpdateLatency(latency);
        healthy = UpdateErrorCost(0, ema_latency);
    } else {
        ema_latency = _ema_latency.load(butil::memory_order_relaxed);
        healthy = UpdateErrorCost(latency, ema_latency);
    }

    if (_sample_count.fetch_add(1, butil::memory_order_relaxed) < _window_size) {
        return true;
    }

    if (!healthy) {
        _broken.store(true, butil::memory_order_relaxed);
    }
    return healthy;
}

void CircuitBreaker::EmaErrorRecorder::Reset() {
    _sample_count.store(0, butil::memory_order_relaxed);
    _ema_error_cost.store(0, butil::memory_order_relaxed);
    _ema_latency.store(0, butil::memory_order_relaxed);
    _broken.store(false, butil::memory_order_relaxed);
}

int64_t CircuitBreaker::EmaErrorRecorder::UpdateLatency(int64_t latency) {
    int64_t ema_latency = _ema_latency.load(butil::memory_order_relaxed);
    do {
        int64_t next_ema_latency = 0;
        if (0 == ema_latency) {
            next_ema_latency = latency;
        } else {
            next_ema_latency = ema_latency * _smooth + latency * (1 - _smooth);
        }
        if (_ema_latency.compare_exchange_weak(ema_latency, next_ema_latency)) {
            return next_ema_latency;
        }
    } while(true);
}

bool CircuitBreaker::EmaErrorRecorder::UpdateErrorCost(int64_t error_cost,
                                                       int64_t ema_latency) {
    const int max_mutilple = FLAGS_circuit_breaker_max_failed_latency_mutilple;
    error_cost = std::min(ema_latency * max_mutilple, error_cost);
    //Errorous response
    if (error_cost != 0) {
        int64_t ema_error_cost =
            _ema_error_cost.fetch_add(error_cost, butil::memory_order_relaxed);
        ema_error_cost += error_cost;
        int64_t max_error_cost = ema_latency * _window_size *
            (_max_error_percent / 100.0) * (1.0 + EPSILON);
        return ema_error_cost <= max_error_cost;
    }

    //Ordinary response
    int64_t ema_error_cost = _ema_error_cost.load(butil::memory_order_relaxed);
    do {
        if (ema_error_cost == 0) {
            break;
        } else if (ema_error_cost < FLAGS_circuit_breaker_min_error_cost_us) {
            if (_ema_error_cost.compare_exchange_weak(
                ema_error_cost, 0, butil::memory_order_relaxed)) {
                break;
            }
        } else {
            int64_t next_ema_error_cost = ema_error_cost * _smooth;
            if (_ema_error_cost.compare_exchange_weak(
                ema_error_cost, next_ema_error_cost)) {
                break;
            }
        }
    } while (true);
    return true;
}

CircuitBreaker::CircuitBreaker()
    : _long_window(FLAGS_circuit_breaker_long_window_size,
                   FLAGS_circuit_breaker_long_window_error_percent)
    , _short_window(FLAGS_circuit_breaker_short_window_size,
                    FLAGS_circuit_breaker_short_window_error_percent) {
}

bool CircuitBreaker::OnCallEnd(int error_code, int64_t latency) {
    return _long_window.OnCallEnd(error_code, latency) &&
           _short_window.OnCallEnd(error_code, latency);
}

void CircuitBreaker::Reset() {
    _long_window.Reset();
    _short_window.Reset();
}

}  // namespace brpc
<commit_msg>change default value of glags for circuit_breaker<commit_after>// Copyright (c) 2014 Baidu, Inc.G
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Authors: Lei He (helei@qiyi.com)

#include <cmath>
#include <gflags/gflags.h>
#include "brpc/circuit_breaker.h"

namespace brpc {

DEFINE_int32(circuit_breaker_short_window_size, 400,
    "Short window sample size.");
DEFINE_int32(circuit_breaker_long_window_size, 1000,
    "Long window sample size.");
DEFINE_int32(circuit_breaker_short_window_error_percent, 10,
    "The maximum error rate allowed by the short window, ranging from 0-99.");
DEFINE_int32(circuit_breaker_long_window_error_percent, 30,
    "The maximum error rate allowed by the long window, ranging from 0-99.");
DEFINE_int32(circuit_breaker_min_error_cost_us, 500,
    "The minimum error_cost, when the ema of error cost is less than this "
    "value, it will be set to zero.");
DEFINE_int32(circuit_breaker_max_failed_latency_mutilple, 3,
    "The maximum multiple of the latency of the failed request relative to "
    "the average latency of the success requests.");

namespace {
// EPSILON is used to generate the smoothing coefficient when calculating EMA.
// The larger the EPSILON, the larger the smoothing coefficient, which means
// that the proportion of early data is larger.
// smooth = pow(EPSILON, 1 / window_size),
// eg: when window_size = 100,
// EPSILON = 0.1, smooth = 0.9772
// EPSILON = 0.3, smooth = 0.9880
// when window_size = 1000,
// EPSILON = 0.1, smooth = 0.9977
// EPSILON = 0.3, smooth = 0.9987
const double EPSILON = 0.1;
}  // namepace

CircuitBreaker::EmaErrorRecorder::EmaErrorRecorder(int window_size,
                                                   int max_error_percent)
    : _window_size(window_size)
    , _max_error_percent(max_error_percent)
    , _smooth(std::pow(EPSILON, 1.0/window_size))
    , _sample_count(0)
    , _ema_error_cost(0)
    , _ema_latency(0)
    , _broken(false) {
}

bool CircuitBreaker::EmaErrorRecorder::OnCallEnd(int error_code,
                                                 int64_t latency) {
    if (_broken.load(butil::memory_order_relaxed)) {
        return false;
    }

    int64_t ema_latency = 0;
    bool healthy = false;
    if (error_code == 0) {
        ema_latency = UpdateLatency(latency);
        healthy = UpdateErrorCost(0, ema_latency);
    } else {
        ema_latency = _ema_latency.load(butil::memory_order_relaxed);
        healthy = UpdateErrorCost(latency, ema_latency);
    }

    if (_sample_count.fetch_add(1, butil::memory_order_relaxed) < _window_size) {
        return true;
    }

    if (!healthy) {
        _broken.store(true, butil::memory_order_relaxed);
    }
    return healthy;
}

void CircuitBreaker::EmaErrorRecorder::Reset() {
    _sample_count.store(0, butil::memory_order_relaxed);
    _ema_error_cost.store(0, butil::memory_order_relaxed);
    _ema_latency.store(0, butil::memory_order_relaxed);
    _broken.store(false, butil::memory_order_relaxed);
}

int64_t CircuitBreaker::EmaErrorRecorder::UpdateLatency(int64_t latency) {
    int64_t ema_latency = _ema_latency.load(butil::memory_order_relaxed);
    do {
        int64_t next_ema_latency = 0;
        if (0 == ema_latency) {
            next_ema_latency = latency;
        } else {
            next_ema_latency = ema_latency * _smooth + latency * (1 - _smooth);
        }
        if (_ema_latency.compare_exchange_weak(ema_latency, next_ema_latency)) {
            return next_ema_latency;
        }
    } while(true);
}

bool CircuitBreaker::EmaErrorRecorder::UpdateErrorCost(int64_t error_cost,
                                                       int64_t ema_latency) {
    const int max_mutilple = FLAGS_circuit_breaker_max_failed_latency_mutilple;
    error_cost = std::min(ema_latency * max_mutilple, error_cost);
    //Errorous response
    if (error_cost != 0) {
        int64_t ema_error_cost =
            _ema_error_cost.fetch_add(error_cost, butil::memory_order_relaxed);
        ema_error_cost += error_cost;
        int64_t max_error_cost = ema_latency * _window_size *
            (_max_error_percent / 100.0) * (1.0 + EPSILON);
        return ema_error_cost <= max_error_cost;
    }

    //Ordinary response
    int64_t ema_error_cost = _ema_error_cost.load(butil::memory_order_relaxed);
    do {
        if (ema_error_cost == 0) {
            break;
        } else if (ema_error_cost < FLAGS_circuit_breaker_min_error_cost_us) {
            if (_ema_error_cost.compare_exchange_weak(
                ema_error_cost, 0, butil::memory_order_relaxed)) {
                break;
            }
        } else {
            int64_t next_ema_error_cost = ema_error_cost * _smooth;
            if (_ema_error_cost.compare_exchange_weak(
                ema_error_cost, next_ema_error_cost)) {
                break;
            }
        }
    } while (true);
    return true;
}

CircuitBreaker::CircuitBreaker()
    : _long_window(FLAGS_circuit_breaker_long_window_size,
                   FLAGS_circuit_breaker_long_window_error_percent)
    , _short_window(FLAGS_circuit_breaker_short_window_size,
                    FLAGS_circuit_breaker_short_window_error_percent) {
}

bool CircuitBreaker::OnCallEnd(int error_code, int64_t latency) {
    return _long_window.OnCallEnd(error_code, latency) &&
           _short_window.OnCallEnd(error_code, latency);
}

void CircuitBreaker::Reset() {
    _long_window.Reset();
    _short_window.Reset();
}

}  // namespace brpc
<|endoftext|>


<commit_before>/*======================================================================

  This file is part of the elastix software.

  Copyright (c) University Medical Center Utrecht. All rights reserved.
  See src/CopyrightElastix.txt or http://elastix.isi.uu.nl/legal.php for
  details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE. See the above copyright notices for more information.

======================================================================*/
#include "elxElastixBase.h"
#include <sstream>
#include "itkMersenneTwisterRandomVariateGenerator.h"

namespace elastix
{

/**
 * ********************* Constructor ****************************
 */

ElastixBase::ElastixBase()
{
  /** Initialize. */
  this->m_Configuration = 0;
  this->m_ComponentDatabase = 0;
  this->m_DBIndex = 0;

  /** The default output precision of elxout is set to 6. */
  this->m_DefaultOutputPrecision = 6;

  /** Create the component containers. */
  this->m_FixedImagePyramidContainer = ObjectContainerType::New();
  this->m_MovingImagePyramidContainer = ObjectContainerType::New();
  this->m_InterpolatorContainer = ObjectContainerType::New();
  this->m_ImageSamplerContainer = ObjectContainerType::New();
  this->m_MetricContainer = ObjectContainerType::New();
  this->m_OptimizerContainer = ObjectContainerType::New();
  this->m_RegistrationContainer = ObjectContainerType::New();
  this->m_ResamplerContainer = ObjectContainerType::New();
  this->m_ResampleInterpolatorContainer = ObjectContainerType::New();
  this->m_TransformContainer = ObjectContainerType::New();

  /** Create image and mask containers. */
  this->m_FixedImageContainer = DataObjectContainerType::New();
  this->m_MovingImageContainer = DataObjectContainerType::New();
  this->m_FixedImageFileNameContainer = FileNameContainerType::New();
  this->m_MovingImageFileNameContainer = FileNameContainerType::New();

  this->m_FixedMaskContainer = DataObjectContainerType::New();
  this->m_MovingMaskContainer = DataObjectContainerType::New();
  this->m_FixedMaskFileNameContainer = FileNameContainerType::New();
  this->m_MovingMaskFileNameContainer = FileNameContainerType::New();

  /** Initialize initialTransform and final transform. */
  this->m_InitialTransform = 0;
  this->m_FinalTransform = 0;

  /** Ignore direction cosines by default, for backward compatability. */
  this->m_UseDirectionCosines = false;

} // end Constructor

/**
 * ********************* SetDBIndex ***********************
 */

void ElastixBase::SetDBIndex( DBIndexType _arg )
{
  /** If m_DBIndex is not set, set it. */
  if ( this->m_DBIndex != _arg )
  {
    this->m_DBIndex = _arg;

    Object * thisasobject = dynamic_cast<Object *>( this );
    if ( thisasobject )
    {
      thisasobject->Modified();
    }
  }

} // end SetDBIndex()

/**
 * ************************ BeforeAllBase ***************************
 */

int ElastixBase::BeforeAllBase( void )
{
  /** Declare the return value and initialize it. */
  int returndummy = 0;

  /** Set the default precision of floating values in the output. */
  this->m_Configuration->ReadParameter(
    this->m_DefaultOutputPrecision, "DefaultOutputPrecision", 0, false );
  elxout << std::setprecision( this->m_DefaultOutputPrecision );

  /** Print to log file. */
  elxout << std::fixed;
  elxout << std::showpoint;
  elxout << std::setprecision( 3 );
  elxout << "ELASTIX version: " << __ELASTIX_VERSION << std::endl;
  elxout << std::setprecision( this->GetDefaultOutputPrecision() );

  /** Check Command line options and print them to the logfile. */
  elxout << "Command line options from ElastixBase:" << std::endl;
  std::string check = "";

  /** Read the fixed and moving image filenames. These are obliged options,
   * so print an error if they are not present.
   * Print also some info (second boolean = true).
   */
  this->m_FixedImageFileNameContainer = this->GenerateFileNameContainer(
    "-f", returndummy, true, true );
  this->m_MovingImageFileNameContainer = this->GenerateFileNameContainer(
    "-m", returndummy, true, true );

  /** Read the fixed and moving mask filenames. These are not obliged options,
   * so do not print any errors if they are not present.
   * Do print some info (second boolean = true).
   */
  int maskreturndummy = 0;
  this->m_FixedMaskFileNameContainer = this->GenerateFileNameContainer(
    "-fMask", maskreturndummy, false, true );
  if ( maskreturndummy != 0 )
  {
    elxout << "-fMask    unspecified, so no fixed mask used" << std::endl;
  }
  maskreturndummy = 0;
  this->m_MovingMaskFileNameContainer = this->GenerateFileNameContainer(
    "-mMask", maskreturndummy, false, true );
  if ( maskreturndummy != 0 )
  {
    elxout << "-mMask    unspecified, so no moving mask used" << std::endl;
  }

  /** Check for appearance of "-out".
   * This check has already been performed in elastix.cxx,
   * Here we do it again.
   */
  check = "";
  check = this->GetConfiguration()->GetCommandLineArgument( "-out" );
  if ( check == "" )
  {
    xl::xout["error"] << "ERROR: No CommandLine option \"-out\" given!" << std::endl;
    returndummy |= 1;
  }
  else
  {
    /** Make sure that last character of -out equals a '/'. */
    std::string folder( check );
    if ( folder.find_last_of( "/" ) != folder.size() - 1 )
    {
      folder.append( "/" );
      this->GetConfiguration()->SetCommandLineArgument( "-out", folder.c_str() );
    }
    elxout << "-out      " << check << std::endl;
  }

  /** Print all "-p". */
  unsigned int i = 1;
  bool loop = true;
  while ( loop )
  {
    check = "";
    std::ostringstream tempPname("");
    tempPname << "-p(" << i << ")";
    check = this->GetConfiguration()->GetCommandLineArgument( tempPname.str().c_str() );
    if ( check == "" ) loop = false;
    else elxout << "-p        " << check << std::endl;
    ++i;
  }

  /** Check for appearance of "-priority", if this is a Windows station. */
  #ifdef _WIN32
  check = "";
  check = this->GetConfiguration()->GetCommandLineArgument( "-priority" );
  if ( check == "" )
  {
    elxout << "-priority unspecified, so NORMAL process priority" << std::endl;
  }
  else
  {
    elxout << "-priority " << check << std::endl;
  }
  #endif

  /** Check for appearance of -threads, which specifies the maximum number of threads. */
  check = "";
  check = this->GetConfiguration()->GetCommandLineArgument( "-threads" );
  if ( check == "" )
  {
    elxout << "-threads  unspecified, so all available threads are used" << std::endl;
  }
  else
  {
    elxout << "-threads  " << check << std::endl;
  }

  /** Check the very important UseDirectionCosines parameter. */
  this->m_UseDirectionCosines = false;
  bool retudc = this->GetConfiguration()->ReadParameter( this->m_UseDirectionCosines,
    "UseDirectionCosines", 0 );
  if ( !retudc )
  {
    xl::xout["warning"]
      << "\nWARNING: From elastix 4.3 it is highly recommended to add\n"
      << "the UseDirectionCosines option to your parameter file! See\n"
      << "http://elastix.isi.uu.nl/whatsnew_04_3.php for more information.\n"
      << std::endl;
  }

  /** Set the random seed. Use 121212 as a default, which is the same as
   * the default in the MersenneTwister code. */
  typedef itk::Statistics::MersenneTwisterRandomVariateGenerator RandomGeneratorType;
  typedef RandomGeneratorType::IntegerType SeedType;
  unsigned int randomSeed = 121212;
  this->GetConfiguration()->ReadParameter( randomSeed, "RandomSeed", 0 );
  RandomGeneratorType::Pointer randomGenerator = RandomGeneratorType::New();
  randomGenerator->SetSeed( static_cast<SeedType>( randomSeed ) );

  /** Return a value. */
  return returndummy;

} // end BeforeAllBase()

/**
 * ************************ BeforeAllTransformixBase ***************************
 */

int ElastixBase::BeforeAllTransformixBase( void )
{
  /** Declare the return value and initialize it. */
  int returndummy = 0;

  /** Print to log file. */
  elxout << std::fixed;
  elxout << std::showpoint;
  elxout << std::setprecision( 3 );
  elxout << "ELASTIX version: " << __ELASTIX_VERSION << std::endl;
  elxout << std::setprecision( this->GetDefaultOutputPrecision() );

  /** Check Command line options and print them to the logfile. */
  elxout << "Command line options from ElastixBase:" << std::endl;
  std::string check = "";

  /** Read the input image filenames. These are not obliged options,
   * so do not print an error if they are not present.
   * Print also some info (second boolean = true)
   * Save the result in the moving image file name container.
   */
  int inreturndummy = 0;
  this->m_MovingImageFileNameContainer = this->GenerateFileNameContainer(
    "-in", inreturndummy, false, true );
  if ( inreturndummy != 0 )
  {
    elxout << "-in       unspecified, so no input image specified" << std::endl;
  }

  /** Check for appearance of "-out". */
  check = this->GetConfiguration()->GetCommandLineArgument( "-out" );
  if ( check == "" )
  {
    xl::xout["error"] << "ERROR: No CommandLine option \"-out\" given!" << std::endl;
    returndummy |= 1;
  }
  else
  {
    /** Make sure that last character of -out equals a '/'. */
    std::string folder( check );
    if ( folder.find_last_of( "/" ) != folder.size() - 1 )
    {
      folder.append( "/" );
      this->GetConfiguration()->SetCommandLineArgument( "-out", folder.c_str() );
    }
    elxout << "-out      " << check << std::endl;
  }

  /** Check for appearance of -threads, which specifies the maximum number of threads. */
  check = "";
  check = this->GetConfiguration()->GetCommandLineArgument( "-threads" );
  if ( check == "" )
  {
    elxout << "-threads  unspecified, so all available threads are used" << std::endl;
  }
  else
  {
    elxout << "-threads  " << check << std::endl;
  }

  /** Print "-tp". */
  check = this->GetConfiguration()->GetCommandLineArgument( "-tp" );
  elxout << "-tp       " << check << std::endl;

  /** Check the very important UseDirectionCosines parameter. */
  this->m_UseDirectionCosines = false;
  bool retudc = this->GetConfiguration()->ReadParameter( this->m_UseDirectionCosines,
    "UseDirectionCosines", 0 );
  if ( !retudc )
  {
    xl::xout["warning"]
      << "\nWARNING: From elastix 4.3 it is highly recommended to add\n"
      << "the UseDirectionCosines option to your parameter file! See\n"
      << "http://elastix.isi.uu.nl/whatsnew_04_3.php for more information.\n"
      << std::endl;
  }

  return returndummy;

} // end BeforeAllTransformixBase()

/**
 * ************************ BeforeRegistrationBase ******************
 */

void ElastixBase::BeforeRegistrationBase( void )
{
  using namespace xl;

  /** Set up the "iteration" writing field. */
  this->m_IterationInfo.SetOutputs( xout.GetCOutputs() );
  this->m_IterationInfo.SetOutputs( xout.GetXOutputs() );

  xout.AddTargetCell( "iteration", &this->m_IterationInfo );

} // end BeforeRegistrationBase()

/**
 * **************** AfterRegistrationBase ***********************
 */

void ElastixBase::AfterRegistrationBase( void )
{
  /** Remove the "iteration" writing field. */
  xl::xout.RemoveTargetCell( "iteration" );

} // end AfterRegistrationBase()

/**
 * ********************* GenerateFileNameContainer ******************
 */

ElastixBase::FileNameContainerPointer
ElastixBase::GenerateFileNameContainer(
  const std::string & optionkey, int & errorcode,
  bool printerrors, bool printinfo ) const
{
  FileNameContainerPointer fileNameContainer = FileNameContainerType::New();
  std::string check = "";
  std::string argused( "" );

  /** Try optionkey0. */
  std::ostringstream argusedss( "" );
  argusedss << optionkey << 0;
  argused = argusedss.str();
  check = this->GetConfiguration()->GetCommandLineArgument( argused.c_str() );
  if ( check == "" )
  {
    /** Try optionkey. */
    std::ostringstream argusedss2( "" );
    argusedss2 << optionkey;
    argused = argusedss2.str();
    check = this->GetConfiguration()->GetCommandLineArgument( argused.c_str() );
    if ( check == "" )
    {
      /** Both failed; return an error message, if desired. */
      if ( printerrors )
      {
        xl::xout["error"]
        << "ERROR: No CommandLine option \""
          << optionkey << "\" or \""
          << optionkey << 0 << "\" given!" << std::endl;
      }
      errorcode |= 1;

      return fileNameContainer;
    }
  }

  /** Optionkey or optionkey0 is found. */
  if ( check != "" )
  {
    /** Print info, if desired. */
    if ( printinfo )
    {
      /** Print the option, with some spaces, followed by the value. */
      int nrSpaces0 = 10 - argused.length();
      unsigned int nrSpaces = nrSpaces0 > 1 ? nrSpaces0 : 1;
      std::string spaces = "";
      spaces.resize( nrSpaces, ' ' );
      elxout << argused << spaces << check << std::endl;
    }
    fileNameContainer->CreateElementAt( 0 ) = check;

    /** Loop over all optionkey<i> options given with i > 0. */
    unsigned int i = 1;
    bool readsuccess = true;
    while ( readsuccess )
    {
      std::ostringstream argusedss2( "" );
      argusedss2 << optionkey << i;
      argused = argusedss2.str();
      check = this->GetConfiguration()->GetCommandLineArgument( argused.c_str() );
      if ( check == "" )
      {
        readsuccess = false;
      }
      else
      {
        if ( printinfo )
        {
          /** Print the option, with some spaces, followed by the value. */
          int nrSpaces0 = 10 - argused.length();
          unsigned int nrSpaces = nrSpaces0 > 1 ? nrSpaces0 : 1;
          std::string spaces = "";
          spaces.resize( nrSpaces, ' ' );
          elxout << argused << spaces << check << std::endl;
        }
        fileNameContainer->CreateElementAt(i) = check;
        ++i;
      }
    } // end while
  } // end if

  return fileNameContainer;

} // end GenerateFileNameContainer()

/**
 * ******************** GetUseDirectionCosines ********************
 */

bool ElastixBase::GetUseDirectionCosines( void ) const
{
  return this->m_UseDirectionCosines;
}

/**
 * ******************** SetOriginalFixedImageDirectionFlat ********************
 */

void ElastixBase::SetOriginalFixedImageDirectionFlat(
  const FlatDirectionCosinesType & arg )
{
  this->m_OriginalFixedImageDirection = arg;
}

/**
 * ******************** GetOriginalFixedImageDirectionFlat ********************
 */

const ElastixBase::FlatDirectionCosinesType &
ElastixBase::GetOriginalFixedImageDirectionFlat( void ) const
{
  return this->m_OriginalFixedImageDirection;
}

} // end namespace elastix

<commit_msg>SK<commit_after>/*======================================================================

  This file is part of the elastix software.

  Copyright (c) University Medical Center Utrecht. All rights reserved.
  See src/CopyrightElastix.txt or http://elastix.isi.uu.nl/legal.php for
  details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE. See the above copyright notices for more information.

======================================================================*/
#include "elxElastixBase.h"
#include <sstream>
#include "itkMersenneTwisterRandomVariateGenerator.h"

namespace elastix
{

/**
 * ********************* Constructor ****************************
 */

ElastixBase::ElastixBase()
{
  /** Initialize. */
  this->m_Configuration = 0;
  this->m_ComponentDatabase = 0;
  this->m_DBIndex = 0;

  /** The default output precision of elxout is set to 6. */
  this->m_DefaultOutputPrecision = 6;

  /** Create the component containers. */
  this->m_FixedImagePyramidContainer = ObjectContainerType::New();
  this->m_MovingImagePyramidContainer = ObjectContainerType::New();
  this->m_InterpolatorContainer = ObjectContainerType::New();
  this->m_ImageSamplerContainer = ObjectContainerType::New();
  this->m_MetricContainer = ObjectContainerType::New();
  this->m_OptimizerContainer = ObjectContainerType::New();
  this->m_RegistrationContainer = ObjectContainerType::New();
  this->m_ResamplerContainer = ObjectContainerType::New();
  this->m_ResampleInterpolatorContainer = ObjectContainerType::New();
  this->m_TransformContainer = ObjectContainerType::New();

  /** Create image and mask containers. */
  this->m_FixedImageContainer = DataObjectContainerType::New();
  this->m_MovingImageContainer = DataObjectContainerType::New();
  this->m_FixedImageFileNameContainer = FileNameContainerType::New();
  this->m_MovingImageFileNameContainer = FileNameContainerType::New();

  this->m_FixedMaskContainer = DataObjectContainerType::New();
  this->m_MovingMaskContainer = DataObjectContainerType::New();
  this->m_FixedMaskFileNameContainer = FileNameContainerType::New();
  this->m_MovingMaskFileNameContainer = FileNameContainerType::New();

  /** Initialize initialTransform and final transform. */
  this->m_InitialTransform = 0;
  this->m_FinalTransform = 0;

  /** Ignore direction cosines by default, for backward compatability. */
  this->m_UseDirectionCosines = false;

} // end Constructor

/**
 * ********************* SetDBIndex ***********************
 */

void ElastixBase::SetDBIndex( DBIndexType _arg )
{
  /** If m_DBIndex is not set, set it. */
  if ( this->m_DBIndex != _arg )
  {
    this->m_DBIndex = _arg;

    Object * thisasobject = dynamic_cast<Object *>( this );
    if ( thisasobject )
    {
      thisasobject->Modified();
    }
  }

} // end SetDBIndex()

/**
 * ************************ BeforeAllBase ***************************
 */

int ElastixBase::BeforeAllBase( void )
{
  /** Declare the return value and initialize it. */
  int returndummy = 0;

  /** Set the default precision of floating values in the output. */
  this->m_Configuration->ReadParameter(
    this->m_DefaultOutputPrecision, "DefaultOutputPrecision", 0, false );
  elxout << std::setprecision( this->m_DefaultOutputPrecision );

  /** Print to log file. */
  elxout << std::fixed;
  elxout << std::showpoint;
  elxout << std::setprecision( 3 );
  elxout << "ELASTIX version: " << __ELASTIX_VERSION << std::endl;
  elxout << std::setprecision( this->GetDefaultOutputPrecision() );

  /** Check Command line options and print them to the logfile. */
  elxout << "Command line options from ElastixBase:" << std::endl;
  std::string check = "";

  /** Read the fixed and moving image filenames. These are obliged options,
   * so print an error if they are not present.
   * Print also some info (second boolean = true).
   */
  this->m_FixedImageFileNameContainer = this->GenerateFileNameContainer(
    "-f", returndummy, true, true );
  this->m_MovingImageFileNameContainer = this->GenerateFileNameContainer(
    "-m", returndummy, true, true );

  /** Read the fixed and moving mask filenames. These are not obliged options,
   * so do not print any errors if they are not present.
   * Do print some info (second boolean = true).
   */
  int maskreturndummy = 0;
  this->m_FixedMaskFileNameContainer = this->GenerateFileNameContainer(
    "-fMask", maskreturndummy, false, true );
  if ( maskreturndummy != 0 )
  {
    elxout << "-fMask    unspecified, so no fixed mask used" << std::endl;
  }
  maskreturndummy = 0;
  this->m_MovingMaskFileNameContainer = this->GenerateFileNameContainer(
    "-mMask", maskreturndummy, false, true );
  if ( maskreturndummy != 0 )
  {
    elxout << "-mMask    unspecified, so no moving mask used" << std::endl;
  }

  /** Check for appearance of "-out".
   * This check has already been performed in elastix.cxx,
   * Here we do it again.
   */
  check = "";
  check = this->GetConfiguration()->GetCommandLineArgument( "-out" );
  if ( check == "" )
  {
    xl::xout["error"] << "ERROR: No CommandLine option \"-out\" given!" << std::endl;
    returndummy |= 1;
  }
  else
  {
    /** Make sure that last character of -out equals a '/'. */
    std::string folder( check );
    if ( folder.find_last_of( "/" ) != folder.size() - 1 )
    {
      folder.append( "/" );
      this->GetConfiguration()->SetCommandLineArgument( "-out", folder.c_str() );
    }
    elxout << "-out      " << check << std::endl;
  }

  /** Print all "-p". */
  unsigned int i = 1;
  bool loop = true;
  while ( loop )
  {
    check = "";
    std::ostringstream tempPname("");
    tempPname << "-p(" << i << ")";
    check = this->GetConfiguration()->GetCommandLineArgument( tempPname.str().c_str() );
    if ( check == "" ) loop = false;
    else elxout << "-p        " << check << std::endl;
    ++i;
  }

  /** Check for appearance of "-priority", if this is a Windows station. */
  #ifdef _WIN32
  check = "";
  check = this->GetConfiguration()->GetCommandLineArgument( "-priority" );
  if ( check == "" )
  {
    elxout << "-priority unspecified, so NORMAL process priority" << std::endl;
  }
  else
  {
    elxout << "-priority " << check << std::endl;
  }
  #endif

  /** Check for appearance of -threads, which specifies the maximum number of threads. */
  check = "";
  check = this->GetConfiguration()->GetCommandLineArgument( "-threads" );
  if ( check == "" )
  {
    elxout << "-threads  unspecified, so all available threads are used" << std::endl;
  }
  else
  {
    elxout << "-threads  " << check << std::endl;
  }

  /** Check the very important UseDirectionCosines parameter. */
  this->m_UseDirectionCosines = false;
  bool retudc = this->GetConfiguration()->ReadParameter( this->m_UseDirectionCosines,
    "UseDirectionCosines", 0 );
  if ( !retudc )
  {
    xl::xout["warning"]
      << "\nWARNING: From elastix 4.3 it is highly recommended to add\n"
      << "the UseDirectionCosines option to your parameter file! See\n"
      << "http://elastix.isi.uu.nl/whatsnew_04_3.php for more information.\n"
      << std::endl;
  }

  /** Set the random seed. Use 121212 as a default, which is the same as
   * the default in the MersenneTwister code.
   * Use silent parameter file readout, to avoid annoying warning when
   * starting elastix */
  typedef itk::Statistics::MersenneTwisterRandomVariateGenerator RandomGeneratorType;
  typedef RandomGeneratorType::IntegerType SeedType;
  unsigned int randomSeed = 121212;
  this->GetConfiguration()->ReadParameter( randomSeed, "RandomSeed", 0, false );
  RandomGeneratorType::Pointer randomGenerator = RandomGeneratorType::New();
  randomGenerator->SetSeed( static_cast<SeedType>( randomSeed ) );

  /** Return a value. */
  return returndummy;

} // end BeforeAllBase()

/**
 * ************************ BeforeAllTransformixBase ***************************
 */

int ElastixBase::BeforeAllTransformixBase( void )
{
  /** Declare the return value and initialize it. */
  int returndummy = 0;

  /** Print to log file. */
  elxout << std::fixed;
  elxout << std::showpoint;
  elxout << std::setprecision( 3 );
  elxout << "ELASTIX version: " << __ELASTIX_VERSION << std::endl;
  elxout << std::setprecision( this->GetDefaultOutputPrecision() );

  /** Check Command line options and print them to the logfile. */
  elxout << "Command line options from ElastixBase:" << std::endl;
  std::string check = "";

  /** Read the input image filenames. These are not obliged options,
   * so do not print an error if they are not present.
   * Print also some info (second boolean = true)
   * Save the result in the moving image file name container.
   */
  int inreturndummy = 0;
  this->m_MovingImageFileNameContainer = this->GenerateFileNameContainer(
    "-in", inreturndummy, false, true );
  if ( inreturndummy != 0 )
  {
    elxout << "-in       unspecified, so no input image specified" << std::endl;
  }

  /** Check for appearance of "-out". */
  check = this->GetConfiguration()->GetCommandLineArgument( "-out" );
  if ( check == "" )
  {
    xl::xout["error"] << "ERROR: No CommandLine option \"-out\" given!" << std::endl;
    returndummy |= 1;
  }
  else
  {
    /** Make sure that last character of -out equals a '/'. */
    std::string folder( check );
    if ( folder.find_last_of( "/" ) != folder.size() - 1 )
    {
      folder.append( "/" );
      this->GetConfiguration()->SetCommandLineArgument( "-out", folder.c_str() );
    }
    elxout << "-out      " << check << std::endl;
  }

  /** Check for appearance of -threads, which specifies the maximum number of threads. */
  check = "";
  check = this->GetConfiguration()->GetCommandLineArgument( "-threads" );
  if ( check == "" )
  {
    elxout << "-threads  unspecified, so all available threads are used" << std::endl;
  }
  else
  {
    elxout << "-threads  " << check << std::endl;
  }

  /** Print "-tp". */
  check = this->GetConfiguration()->GetCommandLineArgument( "-tp" );
  elxout << "-tp       " << check << std::endl;

  /** Check the very important UseDirectionCosines parameter. */
  this->m_UseDirectionCosines = false;
  bool retudc = this->GetConfiguration()->ReadParameter( this->m_UseDirectionCosines,
    "UseDirectionCosines", 0 );
  if ( !retudc )
  {
    xl::xout["warning"]
      << "\nWARNING: From elastix 4.3 it is highly recommended to add\n"
      << "the UseDirectionCosines option to your parameter file! See\n"
      << "http://elastix.isi.uu.nl/whatsnew_04_3.php for more information.\n"
      << std::endl;
  }

  return returndummy;

} // end BeforeAllTransformixBase()

/**
 * ************************ BeforeRegistrationBase ******************
 */

void ElastixBase::BeforeRegistrationBase( void )
{
  using namespace xl;

  /** Set up the "iteration" writing field. */
  this->m_IterationInfo.SetOutputs( xout.GetCOutputs() );
  this->m_IterationInfo.SetOutputs( xout.GetXOutputs() );

  xout.AddTargetCell( "iteration", &this->m_IterationInfo );

} // end BeforeRegistrationBase()

/**
 * **************** AfterRegistrationBase ***********************
 */

void ElastixBase::AfterRegistrationBase( void )
{
  /** Remove the "iteration" writing field. */
  xl::xout.RemoveTargetCell( "iteration" );

} // end AfterRegistrationBase()

/**
 * ********************* GenerateFileNameContainer ******************
 */

ElastixBase::FileNameContainerPointer
ElastixBase::GenerateFileNameContainer(
  const std::string & optionkey, int & errorcode,
  bool printerrors, bool printinfo ) const
{
  FileNameContainerPointer fileNameContainer = FileNameContainerType::New();
  std::string check = "";
  std::string argused( "" );

  /** Try optionkey0. */
  std::ostringstream argusedss( "" );
  argusedss << optionkey << 0;
  argused = argusedss.str();
  check = this->GetConfiguration()->GetCommandLineArgument( argused.c_str() );
  if ( check == "" )
  {
    /** Try optionkey. */
    std::ostringstream argusedss2( "" );
    argusedss2 << optionkey;
    argused = argusedss2.str();
    check = this->GetConfiguration()->GetCommandLineArgument( argused.c_str() );
    if ( check == "" )
    {
      /** Both failed; return an error message, if desired. */
      if ( printerrors )
      {
        xl::xout["error"]
        << "ERROR: No CommandLine option \""
          << optionkey << "\" or \""
          << optionkey << 0 << "\" given!" << std::endl;
      }
      errorcode |= 1;

      return fileNameContainer;
    }
  }

  /** Optionkey or optionkey0 is found. */
  if ( check != "" )
  {
    /** Print info, if desired. */
    if ( printinfo )
    {
      /** Print the option, with some spaces, followed by the value. */
      int nrSpaces0 = 10 - argused.length();
      unsigned int nrSpaces = nrSpaces0 > 1 ? nrSpaces0 : 1;
      std::string spaces = "";
      spaces.resize( nrSpaces, ' ' );
      elxout << argused << spaces << check << std::endl;
    }
    fileNameContainer->CreateElementAt( 0 ) = check;

    /** Loop over all optionkey<i> options given with i > 0. */
    unsigned int i = 1;
    bool readsuccess = true;
    while ( readsuccess )
    {
      std::ostringstream argusedss2( "" );
      argusedss2 << optionkey << i;
      argused = argusedss2.str();
      check = this->GetConfiguration()->GetCommandLineArgument( argused.c_str() );
      if ( check == "" )
      {
        readsuccess = false;
      }
      else
      {
        if ( printinfo )
        {
          /** Print the option, with some spaces, followed by the value. */
          int nrSpaces0 = 10 - argused.length();
          unsigned int nrSpaces = nrSpaces0 > 1 ? nrSpaces0 : 1;
          std::string spaces = "";
          spaces.resize( nrSpaces, ' ' );
          elxout << argused << spaces << check << std::endl;
        }
        fileNameContainer->CreateElementAt(i) = check;
        ++i;
      }
    } // end while
  } // end if

  return fileNameContainer;

} // end GenerateFileNameContainer()

/**
 * ******************** GetUseDirectionCosines ********************
 */

bool ElastixBase::GetUseDirectionCosines( void ) const
{
  return this->m_UseDirectionCosines;
}

/**
 * ******************** SetOriginalFixedImageDirectionFlat ********************
 */

void ElastixBase::SetOriginalFixedImageDirectionFlat(
  const FlatDirectionCosinesType & arg )
{
  this->m_OriginalFixedImageDirection = arg;
}

/**
 * ******************** GetOriginalFixedImageDirectionFlat ********************
 */

const ElastixBase::FlatDirectionCosinesType &
ElastixBase::GetOriginalFixedImageDirectionFlat( void ) const
{
  return this->m_OriginalFixedImageDirection;
}

} // end namespace elastix

<|endoftext|>