コード例 #1
0
ファイル: psview.c プロジェクト: jmzaleski/ivtools-1.2
void PostScriptView::ConstProcs (ostream& out) {
    UList* fonts = GetPSFonts();
    int nfonts = Count(fonts);

    out << "/IdrawDict " << (50 + nfonts) << " dict def\n";
    out << "IdrawDict begin\n\n";

    if (nfonts > 0) {
	for (const char** line = reencodeISO; *line != nil; ++line) {
	    out << *line << "\n";
	}

	for (UList* u = fonts->First(); u != fonts->End(); u = u->Next()) {
	    PSFont* font = GetFont(u);

	    // No way to check if the X font's encoding is iso8859-1, so...
	    if (strncmp(font->GetPrintFont(), "Symbol", 6) != 0) {
		out << "/" << font->GetPrintFont() << " reencodeISO def\n";
	    } else {
		out << "/" << font->GetPrintFont() << " dup findfont def\n";
	    }
	}
	out << "\n";
    }

    out << "/none null def\n";
    out << "/numGraphicParameters 17 def\n";
    out << "/stringLimit 65535 def\n\n";
}
コード例 #2
0
ファイル: syncTools.C プロジェクト: BarisCumhur/OpenFOAM-dev
void Foam::syncTools::swapBoundaryCellPositions
(
    const polyMesh& mesh,
    const UList<point>& cellData,
    List<point>& neighbourCellData
)
{
    if (cellData.size() != mesh.nCells())
    {
        FatalErrorInFunction
            << "Number of cell values " << cellData.size()
            << " is not equal to the number of cells in the mesh "
            << mesh.nCells() << abort(FatalError);
    }

    const polyBoundaryMesh& patches = mesh.boundaryMesh();

    label nBnd = mesh.nFaces()-mesh.nInternalFaces();

    neighbourCellData.setSize(nBnd);

    forAll(patches, patchI)
    {
        const polyPatch& pp = patches[patchI];
        const labelUList& faceCells = pp.faceCells();
        forAll(faceCells, i)
        {
            label bFaceI = pp.start()+i-mesh.nInternalFaces();
            neighbourCellData[bFaceI] = cellData[faceCells[i]];
        }
    }
Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
(
    const Xfer< pointField >& pointLst,
    const Xfer< List<Face> >& faceLst,
    const UList<label>& zoneSizes,
    const UList<word>& zoneNames
)
:
    ParentType(pointLst, faceLst)
{
    if (zoneSizes.size())
    {
        if (zoneNames.size())
        {
            setZones(zoneSizes, zoneNames);
        }
        else
        {
            setZones(zoneSizes);
        }
    }
    else
    {
        setOneZone();
    }
}
コード例 #4
0
void Foam::processorLduInterface::receive
(
    const Pstream::commsTypes commsType,
    UList<Type>& f
) const
{
    if (commsType == Pstream::blocking || commsType == Pstream::scheduled)
    {
        IPstream::read
        (
            commsType,
            neighbProcNo(),
            reinterpret_cast<char*>(f.begin()),
            f.byteSize(),
            tag()
        );
    }
    else if (commsType == Pstream::nonBlocking)
    {
        memcpy(f.begin(), receiveBuf_.begin(), f.byteSize());
    }
    else
    {
        FatalErrorIn("processorLduInterface::receive")
            << "Unsupported communications type " << commsType
            << exit(FatalError);
    }
}
コード例 #5
0
ファイル: UList.C プロジェクト: OpenFOAM/OpenFOAM-dev
bool Foam::UList<T>::operator<(const UList<T>& a) const
{
    for
    (
        const_iterator vi = begin(), ai = a.begin();
        vi < end() && ai < a.end();
        vi++, ai++
    )
    {
        if (*vi < *ai)
        {
            return true;
        }
        else if (*vi > *ai)
        {
            return false;
        }
    }

    if (this->size_ < a.size_)
    {
        return true;
    }
    else
    {
        return false;
    }
}
コード例 #6
0
ファイル: selection.c プロジェクト: barak/ivtools-cvs
void Selection::Sort (GraphicView* views) {
/*
 * Note: this doesn't work if there are views in the selection from more than
 * one GraphicViews.
 */
    Iterator i;
    UList* cur;
    UList* newList = new UList;

    views->First(i);

    while (!views->Done(i) && !_ulist->IsEmpty()) {
        cur = _ulist->First();

        while (cur != _ulist->End()) {
            if (views->GetView(i) == View(cur)) {
                _ulist->Remove(cur);
                newList->Append(cur);
                break;
            } else {
                cur = cur->Next();
            }
        }
        views->Next(i);
    }
    if (!_ulist->IsEmpty()) {
        cerr << "warning: selection contained spurious element(s)\n";
    }
    delete _ulist;
    _ulist = newList;
}
コード例 #7
0
ファイル: boundBox.C プロジェクト: EricAlex/OpenFOAM-dev
void Foam::boundBox::calculate(const UList<point>& points, const bool doReduce)
{
    if (points.empty())
    {
        min_ = Zero;
        max_ = Zero;

        if (doReduce && Pstream::parRun())
        {
            // Use values that get overwritten by reduce minOp, maxOp below
            min_ = point(VGREAT, VGREAT, VGREAT);
            max_ = point(-VGREAT, -VGREAT, -VGREAT);
        }
    }
    else
    {
        min_ = points[0];
        max_ = points[0];


        for (label i = 1; i < points.size(); i++)
        {
            min_ = ::Foam::min(min_, points[i]);
            max_ = ::Foam::max(max_, points[i]);
        }
    }

    // Reduce parallel information
    if (doReduce)
    {
        reduce(min_, minOp<point>());
        reduce(max_, maxOp<point>());
    }
}
コード例 #8
0
void Foam::AMIInterpolation::interpolateToTarget
(
    const UList<Type>& fld,
    const CombineOp& cop,
    List<Type>& result,
    const UList<Type>& defaultValues
) const
{
    if (fld.size() != srcAddress_.size())
    {
        FatalErrorInFunction
            << "Supplied field size is not equal to source patch size" << nl
            << "    source patch   = " << srcAddress_.size() << nl
            << "    target patch   = " << tgtAddress_.size() << nl
            << "    supplied field = " << fld.size()
            << abort(FatalError);
    }

    if (lowWeightCorrection_ > 0)
    {
        if (defaultValues.size() != tgtAddress_.size())
        {
            FatalErrorInFunction
                << "Employing default values when sum of weights falls below "
                << lowWeightCorrection_
                << " but supplied default field size is not equal to target "
                << "patch size" << nl
                << "    default values = " << defaultValues.size() << nl
                << "    target patch   = " << tgtAddress_.size() << nl
                << abort(FatalError);
        }
    }

    result.setSize(tgtAddress_.size());

    if (singlePatchProc_ == -1)
    {
        const mapDistribute& map = srcMapPtr_();

        List<Type> work(fld);
        map.distribute(work);

        forAll(result, facei)
        {
            if (tgtWeightsSum_[facei] < lowWeightCorrection_)
            {
                result[facei] = defaultValues[facei];
            }
            else
            {
                const labelList& faces = tgtAddress_[facei];
                const scalarList& weights = tgtWeights_[facei];

                forAll(faces, i)
                {
                    cop(result[facei], facei, work[faces[i]], weights[i]);
                }
            }
        }
    }
コード例 #9
0
// Construct as the bounding box of the given pointField
Foam::treeBoundBox::treeBoundBox
(
    const UList<point>& points,
    const UList<label>& meshPoints
)
:
    boundBox()
{
    if (points.empty() || meshPoints.empty())
    {
        WarningIn
        (
            "treeBoundBox::treeBoundBox"
            "(const UList<point>&, const UList<label>&)"
        )   << "cannot find bounding box for zero-sized pointField"
            << "returning zero" << endl;

        return;
    }

    min() = points[meshPoints[0]];
    max() = points[meshPoints[0]];

    for (label i = 1; i < meshPoints.size(); i++)
    {
        min() = ::Foam::min(min(), points[meshPoints[i]]);
        max() = ::Foam::max(max(), points[meshPoints[i]]);
    }
}
コード例 #10
0
void Foam::fileFormats::OFSsurfaceFormatCore::writeHeader
(
    Ostream& os,
    const pointField& pointLst,
    const UList<surfZone>& zoneLst
)
{
    // just emit some information until we get a nice IOobject
    IOobject::writeBanner(os)
        << "// OpenFOAM Surface Format - written "
        << clock::dateTime().c_str() << nl
        << "// ~~~~~~~~~~~~~~~~~~~~~~~" << nl << nl
        << "// surfZones:" << nl;


    // treat a single zone as being unzoned
    if (zoneLst.size() <= 1)
    {
        os  << "0" << token::BEGIN_LIST << token::END_LIST << nl << nl;
    }
    else
    {
        os  << zoneLst.size() << nl << token::BEGIN_LIST << incrIndent << nl;

        forAll(zoneLst, zoneI)
        {
            zoneLst[zoneI].writeDict(os);
        }
        os  << decrIndent << token::END_LIST << nl << nl;
    }
コード例 #11
0
ファイル: scalarField.C プロジェクト: jpola/RapidCFD-dev
scalar sumProd(const UList<scalar>& f1, const UList<scalar>& f2)
{
    if (f1.size() && (f1.size() == f2.size()))
    {
        scalar SumProd = 0.0;
        TFOR_ALL_S_OP_F_OP_F(scalar, SumProd, +=, scalar, f1, *, scalar, f2)
        return SumProd;
    }
コード例 #12
0
ファイル: psview.c プロジェクト: jmzaleski/ivtools-1.2
static int Count (UList* list) {
    int i = 0;

    for (UList* u = list->First(); u != list->End(); u = u->Next()) {
        ++i;
    }
    return i;
}
コード例 #13
0
void Foam::processorLduInterface::send
(
    const Pstream::commsTypes commsType,
    const UList<Type>& f
) const
{
    label nBytes = f.byteSize();

    if
    (
        commsType == Pstream::commsTypes::blocking
     || commsType == Pstream::commsTypes::scheduled
    )
    {
        OPstream::write
        (
            commsType,
            neighbProcNo(),
            reinterpret_cast<const char*>(f.begin()),
            nBytes,
            tag(),
            comm()
        );
    }
    else if (commsType == Pstream::commsTypes::nonBlocking)
    {
        resizeBuf(receiveBuf_, nBytes);

        IPstream::read
        (
            commsType,
            neighbProcNo(),
            receiveBuf_.begin(),
            nBytes,
            tag(),
            comm()
        );

        resizeBuf(sendBuf_, nBytes);
        memcpy(sendBuf_.begin(), f.begin(), nBytes);

        OPstream::write
        (
            commsType,
            neighbProcNo(),
            sendBuf_.begin(),
            nBytes,
            tag(),
            comm()
        );
    }
    else
    {
        FatalErrorInFunction
            << "Unsupported communications type " << int(commsType)
            << exit(FatalError);
    }
}
コード例 #14
0
ファイル: psview.c プロジェクト: jmzaleski/ivtools-1.2
static boolean Uncollected (const char* name, UList* fonts) {
    for (UList* u = fonts->First(); u != fonts->End(); u = u->Next()) {
        PSFont* font = (PSFont*) (*u)();

        if (strcmp(font->GetPrintFont(), name) == 0) {
            return false;
        }
    }
    return true;
}
コード例 #15
0
ファイル: ovcomps.c プロジェクト: jmzaleski/ivtools-1.2
OverlayView* OverlayComp::FindView (Viewer* viewer) {
    if (!_views) return nil;
    for (UList* u = _views->First(); u != _views->End(); u = u->Next()) {
	ComponentView* compview = View(u);
	if (compview->IsA(OVERLAY_VIEW) && 
	    ((OverlayView*)compview)->GetViewer() == viewer) 
	    return (OverlayView*)compview;
    }
    return nil;
}
コード例 #16
0
void Foam::processorLduInterface::compressedReceive
(
    const Pstream::commsTypes commsType,
    UList<Type>& f
) const
{
    if (sizeof(scalar) != sizeof(float) && Pstream::floatTransfer && f.size())
    {
        static const label nCmpts = sizeof(Type)/sizeof(scalar);
        label nm1 = (f.size() - 1)*nCmpts;
        label nlast = sizeof(Type)/sizeof(float);
        label nFloats = nm1 + nlast;
        label nBytes = nFloats*sizeof(float);

        if
        (
            commsType == Pstream::commsTypes::blocking
         || commsType == Pstream::commsTypes::scheduled
        )
        {
            resizeBuf(receiveBuf_, nBytes);

            IPstream::read
            (
                commsType,
                neighbProcNo(),
                receiveBuf_.begin(),
                nBytes,
                tag(),
                comm()
            );
        }
        else if (commsType != Pstream::commsTypes::nonBlocking)
        {
            FatalErrorInFunction
                << "Unsupported communications type " << int(commsType)
                << exit(FatalError);
        }

        const float *fArray =
            reinterpret_cast<const float*>(receiveBuf_.begin());
        f.last() = reinterpret_cast<const Type&>(fArray[nm1]);
        scalar *sArray = reinterpret_cast<scalar*>(f.begin());
        const scalar *slast = &sArray[nm1];

        for (label i=0; i<nm1; i++)
        {
            sArray[i] = fArray[i] + slast[i%nCmpts];
        }
    }
    else
    {
        this->receive<Type>(commsType, f);
    }
}
コード例 #17
0
ファイル: exchange.C プロジェクト: jheylmun/OpenFOAM-dev
void Foam::Pstream::exchange
(
    const UList<Container>& sendBufs,
    const labelUList& recvSizes,
    List<Container>& recvBufs,
    const int tag,
    const label comm,
    const bool block
)
{
    if (!contiguous<T>())
    {
        FatalErrorInFunction
            << "Continuous data only." << sizeof(T) << Foam::abort(FatalError);
    }

    if (sendBufs.size() != UPstream::nProcs(comm))
    {
        FatalErrorInFunction
            << "Size of list " << sendBufs.size()
            << " does not equal the number of processors "
            << UPstream::nProcs(comm)
            << Foam::abort(FatalError);
    }

    recvBufs.setSize(sendBufs.size());

    recvBufs.setSize(sendBufs.size());

    if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
    {
        label startOfRequests = Pstream::nRequests();

        // Set up receives
        // ~~~~~~~~~~~~~~~

        forAll(recvSizes, proci)
        {
            label nRecv = recvSizes[proci];

            if (proci != Pstream::myProcNo(comm) && nRecv > 0)
            {
                recvBufs[proci].setSize(nRecv);
                UIPstream::read
                (
                    UPstream::commsTypes::nonBlocking,
                    proci,
                    reinterpret_cast<char*>(recvBufs[proci].begin()),
                    nRecv*sizeof(T),
                    tag,
                    comm
                );
            }
        }
コード例 #18
0
ファイル: VTKedgeFormat.C プロジェクト: 000861/OpenFOAM-2.1.x
void Foam::fileFormats::VTKedgeFormat::writeEdges
(
    Ostream& os,
    const UList<edge>& edgeLst
)
{
    os  << "LINES " << edgeLst.size() << ' ' << 3*edgeLst.size() << nl;

    forAll(edgeLst, edgeI)
    {
        const edge& e = edgeLst[edgeI];

        os  << "2 " << e[0] << ' ' << e[1] << nl;
    }
}
コード例 #19
0
ファイル: uhash.cpp プロジェクト: PNCG/neuron
UHashElem* UHashTable::Find (void* key) {
    int n = Hash(key);
    UList* slot = _slot[n];

    if (slot != nil) {
        for (UList* u = slot->First(); u != slot->End(); u = u->Next()) {
            UHashElem* elem = Elem(u);

            if (Equal(elem->GetKey(), key)) {
                return elem;
            }
        }
    }
    return nil;
}
コード例 #20
0
ファイル: geomobjs.c プロジェクト: barak/ivtools-cvs
MultiLineObj::~MultiLineObj() {
#ifdef LEAKCHECK
    _leakchecker->destroy();
#endif
    if (_ulist) {
	UList* head = _pts_by_n[count()];
	head->Remove(_ulist);
	delete _ulist;
	delete _x;
	delete _y;
    } else if (_pts_made) {
        delete _x;
	delete _y;
    }
}
コード例 #21
0
ファイル: drawcomps.c プロジェクト: barak/ivtools-cvs
Component* DrawIdrawComp::Copy () {
    DrawIdrawComp* comps = new DrawIdrawComp(GetPathName());
    if (attrlist()) comps->SetAttributeList(new AttributeList(attrlist()));
    Iterator i;
    First(i);
    while (!Done(i)) {
	comps->Append((GraphicComp*)GetComp(i)->Copy());
	Next(i);
    }
    for (UList* u = _graphedges->First(); u != _graphedges->End(); u = u->Next()) {
      EdgeComp* edgecomp = (EdgeComp*) (*u)();
      comps->AppendEdge(edgecomp);
    }
    return comps;
}
コード例 #22
0
ファイル: DecoupledCoeffField.C プロジェクト: Brzous/WindFOAM
inline void Foam::DecoupledCoeffField<Type>::checkSize
(
    const UList<Type2>& f
) const
{
    if (f.size() != this->size())
    {
        FatalErrorIn
        (
            "void DecoupledCoeffField<Type>::checkSize("
            "const Field<Type2>& f) const"
        )   << "Incorrect field size: " << f.size()
            << " local size: " << size()
            << abort(FatalError);
    }
}
コード例 #23
0
ファイル: mergePoints.C プロジェクト: Kiiree/CONSELFcae-dev
Foam::label Foam::mergePoints
(
    const UList<Type>& points,
    const scalar mergeTol,
    const bool verbose,
    labelList& pointMap,
    const Type& origin
)
{
    Type compareOrigin = origin;

    if (origin == Type::max)
    {
        if (points.size())
        {
            compareOrigin = sum(points)/points.size();
        }
    }

    // Create a old to new point mapping array
    pointMap.setSize(points.size());
    pointMap = -1;

    if (points.empty())
    {
        return points.size();
    }

    // We're comparing distance squared to origin first.
    // Say if starting from two close points:
    //     x, y, z
    //     x+mergeTol, y+mergeTol, z+mergeTol
    // Then the magSqr of both will be
    //     x^2+y^2+z^2
    //     x^2+y^2+z^2 + 2*mergeTol*(x+z+y) + mergeTol^2*...
    // so the difference will be 2*mergeTol*(x+y+z)

    const scalar mergeTolSqr = Foam::sqr(scalar(mergeTol));

    // Sort points by magSqr
    const Field<Type> d(points - compareOrigin);

    List<scalar> magSqrD(d.size());
    forAll(d, pointI)
    {
        magSqrD[pointI] = magSqr(d[pointI]);
    }
コード例 #24
0
void Foam::globalIndex::gather
(
    const labelUList& off,
    const label comm,
    const labelList& procIDs,
    const UList<Type>& fld,
    List<Type>& allFld,
    const int tag,
    const Pstream::commsTypes commsType
)
{
    if (Pstream::myProcNo(comm) == procIDs[0])
    {
        allFld.setSize(off.last());

        // Assign my local data
        SubList<Type>(allFld, fld.size(), 0) = fld;

        if
        (
            commsType == Pstream::commsTypes::scheduled
         || commsType == Pstream::commsTypes::blocking
        )
        {
            for (label i = 1; i < procIDs.size(); i++)
            {
                SubList<Type> procSlot(allFld, off[i+1]-off[i], off[i]);

                if (contiguous<Type>())
                {
                    IPstream::read
                    (
                        commsType,
                        procIDs[i],
                        reinterpret_cast<char*>(procSlot.begin()),
                        procSlot.byteSize(),
                        tag,
                        comm
                    );
                }
                else
                {
                    IPstream fromSlave
                    (
                        commsType,
                        procIDs[i],
                        0,
                        tag,
                        comm
                    );
                    fromSlave >> procSlot;
                }
            }
        }
        else
        {
            // nonBlocking

            if (!contiguous<Type>())
コード例 #25
0
void Foam::fileFormats::VTKsurfaceFormat<Face>::writeHeaderPolygons
(
    Ostream& os,
    const UList<Face>& faceLst
)
{
    label nNodes = 0;

    forAll(faceLst, faceI)
    {
        nNodes += faceLst[faceI].size();
    }

    os  << nl
        << "POLYGONS " << faceLst.size() << ' '
        << faceLst.size() + nNodes << nl;
}
コード例 #26
0
ファイル: HashSet.C プロジェクト: 000861/OpenFOAM-2.1.x
Foam::HashSet<Key, Hash>::HashSet(const UList<Key>& lst)
:
    HashTable<nil, Key, Hash>(2*lst.size())
{
    forAll(lst, elemI)
    {
        this->insert(lst[elemI]);
    }
コード例 #27
0
ファイル: ibdialog.c プロジェクト: LambdaCalculus379/SLS-1.02
void DialogClass::Interpret(Command* cmd) {
    if (cmd->IsA(GETCONFLICT_CMD)) {
        GetConflictCmd* gcmd = (GetConflictCmd*) cmd;
        const char* cname = gcmd->GetCName();
        MonoSceneClass::Interpret(cmd);
        UList* conflictlist = gcmd->GetConflict();
        ButtonSharedName* bsnamer = _bsVar->GetButtonSharedName();
        const char* buttonname = bsnamer->GetName();
        const char* funcname = bsnamer->GetFuncName();
        if (strcmp(buttonname, cname) == 0 || strcmp(funcname, cname) == 0) {
            conflictlist->Append(new UList(bsnamer));
        }

    } else {
        MonoSceneClass::Interpret(cmd);
    }
}
コード例 #28
0
// Find cut cells
void Foam::cuttingPlane::calcCutCells
(
    const primitiveMesh& mesh,
    const scalarField& dotProducts,
    const UList<label>& cellIdLabels
)
{
    const labelListList& cellEdges = mesh.cellEdges();
    const edgeList& edges = mesh.edges();

    label listSize = cellEdges.size();
    if (&cellIdLabels)
    {
        listSize = cellIdLabels.size();
    }

    cutCells_.setSize(listSize);
    label cutcellI(0);

    // Find the cut cells by detecting any cell that uses points with
    // opposing dotProducts.
    for (label listI = 0; listI < listSize; ++listI)
    {
        label cellI = listI;
        if (&cellIdLabels)
        {
            cellI = cellIdLabels[listI];
        }

        const labelList& cEdges = cellEdges[cellI];

        label nCutEdges = 0;

        forAll(cEdges, i)
        {
            const edge& e = edges[cEdges[i]];

            if
            (
                (dotProducts[e[0]] < zeroish && dotProducts[e[1]] > positive)
             || (dotProducts[e[1]] < zeroish && dotProducts[e[0]] > positive)
            )
            {
                nCutEdges++;

                if (nCutEdges > 2)
                {
                    cutCells_[cutcellI++] = cellI;

                    break;
                }
            }
        }
    }

    // Set correct list size
    cutCells_.setSize(cutcellI);
}
コード例 #29
0
ファイル: ibeditor.c プロジェクト: LambdaCalculus379/SLS-1.02
void EditorComp::GetExtraConflict(GetConflictCmd* gcmd) {
    const char* cname = gcmd->GetCName();
    UList* conflictlist = gcmd->GetConflict();

    const char* curCtrl = _curCtrlVar->GetName();
    const char* key = _keymap->GetName();
    const char* select = _selection->GetName();
    
    const char* ctrl_sub = _curCtrlVar->GetSubclassName();
    const char* key_sub = _keymap->GetSubclass()->GetName();
    const char* sel_sub = _selection->GetSubclass()->GetName();
    
    if (strcmp(curCtrl, cname) == 0) {
        conflictlist->Append(new UList(_curCtrlVar->GetButtonSharedName()));
    }
    if (strcmp(key, cname) == 0) {
        conflictlist->Append(new UList(_keymap->GetMemberSharedName()));
    }
    if (strcmp(select, cname) == 0) {
        conflictlist->Append(new UList(_selection->GetMemberSharedName()));
    }
    if (strcmp(ctrl_sub, cname) == 0) {
        conflictlist->Append(
            new UList(_curCtrlVar->GetButtonSharedName()->GetSubclass())
        );
    }
    if (strcmp(key_sub, cname) == 0) {
        conflictlist->Append(new UList(_keymap->GetSubclass()));
    }
    if (strcmp(sel_sub, cname) == 0) {
        conflictlist->Append(new UList(_selection->GetSubclass()));
    }
    _igrcomps->Interpret(gcmd);
}
コード例 #30
0
ファイル: geomobjs.c プロジェクト: barak/ivtools-cvs
MultiLineObj* MultiLineObj::make_pts (const Coord* x, const Coord* y, int npts) {
    if (!_pts_by_n_enabled) {
        Coord *copyx, *copyy;
	ArrayDup(x, y, npts, copyx, copyy);
	MultiLineObj* mlo = new MultiLineObj(copyx, copyy, npts);
	mlo->_pts_made = 1;
	return mlo;
    }

    if (!_pts_by_n) {
	_pts_by_n = new UList*[_pts_by_n_size];
	for (int i=0; i<_pts_by_n_size; i++) 
	    _pts_by_n[i] = nil;
    }
    if (npts>=_pts_by_n_size) {
	int new_size = max(_pts_by_n_size*2, npts+1);
	UList** new_pts_by_n = new UList*[new_size];
	int i = 0;
	for (;i<_pts_by_n_size; i++) 
	    new_pts_by_n[i] = _pts_by_n[i];
	for (;i<new_size; i++) 
	    new_pts_by_n[i] = nil;
	delete _pts_by_n;
	_pts_by_n = new_pts_by_n;
	_pts_by_n_size = new_size;
    }

    if (_pts_by_n[npts]) {

	MultiLineObj temp_mlo((int*)x, (int*)y, npts);
	UList* ptr = _pts_by_n[npts]->First();
	while (ptr != _pts_by_n[npts]->End()) {
	    if (*(MultiLineObj*)(*ptr)() == temp_mlo) 
		return (MultiLineObj*)(*ptr)();
	    ptr = ptr->Next();
	}
    } else 
	_pts_by_n[npts] = new UList();
    
    Coord *copyx, *copyy;
    ArrayDup(x, y, npts, copyx, copyy);
    MultiLineObj* mlo = new MultiLineObj(copyx, copyy, npts);
    _pts_by_n[npts]->Append(mlo->_ulist = new UList(mlo));
    return mlo;
}