vtkMNIObjectWriter.cxx 24.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkMNIObjectWriter.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm 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 notice for more information.

=========================================================================*/
/*=========================================================================

Copyright (c) 2006 Atamai, Inc.

Use, modification and redistribution of the software, in source or
binary forms, are permitted provided that the following terms and
conditions are met:

1) Redistribution of the source code, in verbatim or modified
   form, must retain the above copyright notice, this license,
   the following disclaimer, and any notices that refer to this
   license and/or the following disclaimer.

2) Redistribution in binary form must include the above copyright
   notice, a copy of this license and the following disclaimer
   in the documentation or with other materials provided with the
   distribution.

3) Modified copies of the source code must be clearly marked as such,
   and must not be misrepresented as verbatim copies of the source code.

THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE SOFTWARE "AS IS"
WITHOUT EXPRESSED OR IMPLIED WARRANTY INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.  IN NO EVENT SHALL ANY COPYRIGHT HOLDER OR OTHER PARTY WHO MAY
MODIFY AND/OR REDISTRIBUTE THE SOFTWARE UNDER THE TERMS OF THIS LICENSE
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, LOSS OF DATA OR DATA BECOMING INACCURATE
OR LOSS OF PROFIT OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF
THE USE OR INABILITY TO USE THE SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.

=========================================================================*/

#include "vtkMNIObjectWriter.h"

#include "vtkObjectFactory.h"

#include "vtkPolyData.h"
#include "vtkPointData.h"
#include "vtkCellData.h"
#include "vtkPoints.h"
#include "vtkCellArray.h"
#include "vtkFloatArray.h"
59
#include "vtkInformation.h"
60 61 62
#include "vtkIntArray.h"
#include "vtkUnsignedCharArray.h"
#include "vtkProperty.h"
63
#include "vtkMapper.h"
64 65 66 67 68
#include "vtkLookupTable.h"
#include "vtkPolygon.h"
#include "vtkMath.h"
#include "vtkErrorCode.h"

Sean McBride's avatar
Sean McBride committed
69 70
#include <cctype>
#include <cmath>
71 72 73 74 75 76 77 78 79 80 81

#if !defined(_WIN32) || defined(__CYGWIN__)
# include <unistd.h> /* unlink */
#else
# include <io.h> /* unlink */
#endif

//--------------------------------------------------------------------------
vtkStandardNewMacro(vtkMNIObjectWriter);

vtkCxxSetObjectMacro(vtkMNIObjectWriter, Property, vtkProperty);
82
vtkCxxSetObjectMacro(vtkMNIObjectWriter, Mapper, vtkMapper);
83 84 85 86 87 88
vtkCxxSetObjectMacro(vtkMNIObjectWriter, LookupTable, vtkLookupTable);

//-------------------------------------------------------------------------
vtkMNIObjectWriter::vtkMNIObjectWriter()
{
  this->Property = 0;
89
  this->Mapper = 0;
90 91
  this->LookupTable = 0;

92 93
  this->FileName = 0;

94 95 96 97 98 99 100 101 102 103
  // Whether file is binary or ASCII
  this->FileType = VTK_ASCII;

  this->OutputStream = 0;
}

//-------------------------------------------------------------------------
vtkMNIObjectWriter::~vtkMNIObjectWriter()
{
  if (this->Property)
104
  {
105
    this->Property->Delete();
106
  }
107
  if (this->Mapper)
108
  {
109
    this->Mapper->Delete();
110
  }
111
  if (this->LookupTable)
112
  {
113
    this->LookupTable->Delete();
114
  }
115 116

  delete[] this->FileName;
117 118 119 120 121 122 123 124
}

//-------------------------------------------------------------------------
void vtkMNIObjectWriter::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  os << indent << "Property: " << this->Property << "\n";
125
  os << indent << "Mapper: " << this->Mapper << "\n";
126 127 128 129 130 131 132
  os << indent << "LookupTable: " << this->LookupTable << "\n";
}

//-------------------------------------------------------------------------
int vtkMNIObjectWriter::WriteObjectType(int objType)
{
  if (this->FileType == VTK_ASCII)
133
  {
134
    this->OutputStream->put(char(objType));
135
  }
136
  else
137
  {
138
    this->OutputStream->put(char(tolower(objType)));
139
  }
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154

  return 1;
}

//-------------------------------------------------------------------------
// Write floating-point values into a vtkFloatArray.
int vtkMNIObjectWriter::WriteValues(vtkDataArray *array)
{
  int dataType = array->GetDataType();
  void *data = array->GetVoidPointer(0);

  vtkIdType numTuples = array->GetNumberOfTuples();
  vtkIdType numComponents = array->GetNumberOfComponents();
  vtkIdType n = numTuples * numComponents;

155
  if (this->FileType == VTK_ASCII && dataType == VTK_UNSIGNED_CHAR)
156
  {
157 158
    vtkIdType m = numComponents;
    for (vtkIdType i = 0; i < n; i += m)
159
    {
160 161 162 163 164 165 166 167 168
      unsigned char *cdata = static_cast<unsigned char *>(data) + i;
      ostream &os = *this->OutputStream;

      double r = cdata[0]/255.0;
      double g = r;
      double b = r;
      double a = 1.0;

      if (m > 2)
169
      {
170 171
        g = cdata[1]/255.0;
        b = cdata[2]/255.0;
172
      }
173
      if (m == 2 || m == 4)
174
      {
175
        a = cdata[m-1]/255.0;
176
      }
177 178 179 180

      os << " " << r << " " << g << " " << b << " " << a;

      if (this->WriteNewline() == 0)
181
      {
182 183 184
        return 0;
      }
    }
185
  }
186
  else if (this->FileType == VTK_ASCII)
187
  {
188 189
    vtkIdType valuesPerLine = 8;
    if (numComponents > 1 && numComponents < 8)
190
    {
191
      valuesPerLine = numComponents;
192
    }
193 194 195

    vtkIdType i = 0;
    while (i < n)
196
    {
197
      for (vtkIdType j = 0; j < valuesPerLine && i < n; i++, j++)
198
      {
199 200 201
        ostream &os = *this->OutputStream;

        switch(dataType)
202
        {
203
          case VTK_FLOAT:
204
          {
205 206 207
            float *fdata = static_cast<float *>(data);
            double val = fdata[i];
            os << " " << val;
208
          }
209 210
            break;
          case VTK_DOUBLE:
211
          {
212 213 214
            double *ddata = static_cast<double *>(data);
            double val = ddata[i];
            os << " " << val;
215
          }
216 217
            break;
          case VTK_INT:
218
          {
219 220 221 222
            int *idata = static_cast<int *>(data);
            int val = idata[i];
            os << " " << val;
          }
223
            break;
224
        }
225
      }
226
      if (this->WriteNewline() == 0)
227
      {
228 229 230
        return 0;
      }
    }
231
  }
232
  else
233
  {
234 235
    // machine-order endianness and data size
    if (dataType == VTK_UNSIGNED_CHAR)
236
    {
237 238
      // colors need to be swapped to ABGR order for binary
      char *odata = static_cast<char *>(data);
239 240
      vtkIdType m = numComponents;
      for (vtkIdType i = 0; i < n && this->OutputStream->good(); i += m)
241
      {
242
        char cdata[4];
243
        if (m > 2)
244
        {
245 246 247
          cdata[3] = odata[0];
          cdata[2] = odata[1];
          cdata[1] = odata[2];
248
        }
249
        else
250
        {
251 252 253
          cdata[3] = odata[0];
          cdata[2] = odata[0];
          cdata[1] = odata[0];
254
        }
255
        if (m == 2 || m == 4)
256
        {
257
          cdata[0] = odata[m-1];
258
        }
259
        else
260
        {
261
          cdata[0] = static_cast<char>(255);
262
        }
263 264 265

        this->OutputStream->write(cdata, 4);

266
        odata += m;
267
      }
268
    }
269
    else if (dataType == VTK_DOUBLE)
270
    {
271 272 273
      // doubles must be converted to float
      double *ddata = (double *)(data);
      for (vtkIdType i = 0; i < n && this->OutputStream->good(); i++)
274
      {
275 276 277
        float fval = ddata[i];
        this->OutputStream->write((char *)(&fval), sizeof(float));
      }
278
    }
279
    else
280
    {
281 282
      this->OutputStream->write((char *)(data),
                                n*array->GetDataTypeSize());
283
    }
284 285

    if (this->OutputStream->fail())
286
    {
287 288 289
      this->SetErrorCode(vtkErrorCode::OutOfDiskSpaceError);
      return 0;
    }
290
  }
291 292 293 294 295 296 297 298 299 300 301

  return 1;
}

//-------------------------------------------------------------------------
int vtkMNIObjectWriter::WriteIdValue(vtkIdType value)
{
  // The .obj files use 32-bit integers exclusively
  int ival = static_cast<int>(value);

  if (this->FileType == VTK_ASCII)
302
  {
303
    *this->OutputStream << " " << ival;
304
  }
305
  else
306
  {
307 308
    // machine-order endianness and data size
    this->OutputStream->write((char *)(&ival), sizeof(int));
309
  }
310 311 312 313 314 315 316 317

  return 1;
}

//-------------------------------------------------------------------------
int vtkMNIObjectWriter::WriteNewline()
{
  if (this->FileType == VTK_ASCII)
318
  {
319 320 321 322
    *this->OutputStream << "\n";

    this->OutputStream->flush();
    if (this->OutputStream->fail())
323
    {
324 325 326
      this->SetErrorCode(vtkErrorCode::OutOfDiskSpaceError);
      return 0;
    }
327
  }
328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343

  return 1;
}

//-------------------------------------------------------------------------
int vtkMNIObjectWriter::WriteProperty(vtkProperty *property)
{
  float properties[5];

  properties[0] = 0.0;
  properties[1] = 1.0;
  properties[2] = 0.0;
  properties[3] = 1.0;
  properties[4] = 1.0;

  if (property)
344
  {
345 346 347 348 349
    properties[0] = property->GetAmbient();
    properties[1] = property->GetDiffuse();
    properties[2] = property->GetSpecular();
    properties[3] = property->GetSpecularPower();
    properties[4] = property->GetOpacity();
350
  }
351 352

  if (this->FileType == VTK_ASCII)
353
  {
354
    for (int i = 0; i < 5; i++)
355
    {
356 357
      *this->OutputStream << " " << properties[i];
    }
358
  }
359
  else
360
  {
361 362
    // machine-order endianness and data size
    this->OutputStream->write((char *)(properties), 5*sizeof(float));
363
  }
364 365 366 367 368 369 370 371 372 373

  return 1;
}

//-------------------------------------------------------------------------
int vtkMNIObjectWriter::WriteLineThickness(vtkProperty *property)
{
  float width = 1;

  if (property)
374
  {
375
    width = property->GetLineWidth();
376
  }
377 378

  if (this->FileType == VTK_ASCII)
379
  {
380
    *this->OutputStream << " " << width;
381
  }
382
  else
383
  {
384 385
    // machine-order endianness and data size
    this->OutputStream->write((char *)(&width), sizeof(float));
386
  }
387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404

  return 1;
}

//-------------------------------------------------------------------------
int vtkMNIObjectWriter::WritePoints(vtkPolyData *data)
{
  return this->WriteValues(data->GetPoints()->GetData());
}

//-------------------------------------------------------------------------
int vtkMNIObjectWriter::WriteNormals(vtkPolyData *data)
{
  vtkDataArray *normals = data->GetPointData()->GetNormals();
  vtkFloatArray *newNormals = 0;

  // Calculate normals if necessary
  if (!normals)
405
  {
406 407 408 409 410 411 412 413 414 415 416 417 418 419
    // Normals will be calculated according to BIC conventions,
    // which weighs the polygon normals by the interior angle.

    vtkPoints *points = data->GetPoints();
    vtkIdType numPoints = points->GetNumberOfPoints();
    vtkCellArray *polyArray = data->GetPolys();
    vtkCellArray *stripArray = data->GetStrips();
    vtkIdType numPolys = data->GetNumberOfPolys();
    vtkIdType numCells = numPolys + data->GetNumberOfStrips();

    newNormals = vtkFloatArray::New();
    newNormals->SetNumberOfComponents(3);
    newNormals->SetNumberOfTuples(numPoints);

David Gobbi's avatar
David Gobbi committed
420
    for (vtkIdType ii = 0; ii < numPoints; ii++)
421
    {
David Gobbi's avatar
David Gobbi committed
422
      float *normal = newNormals->GetPointer(3*ii);
423 424 425
      normal[0] = 0.0;
      normal[1] = 0.0;
      normal[2] = 0.0;
426
    }
427 428 429 430

    vtkIdType polyIndex = 0;
    vtkIdType stripIndex = 0;
    for (vtkIdType i = 0; i < numCells; i++)
431
    {
432 433 434 435 436
      vtkIdType *pointIds;
      vtkIdType numIds;
      vtkIdType numFaces = 1;

      if (i < numPolys)
437
      {
438 439
        polyArray->GetCell(polyIndex, numIds, pointIds);
        polyIndex += 1 + numIds;
440
      }
441
      else
442
      {
443 444 445 446
        stripArray->GetCell(stripIndex, numIds, pointIds);
        stripIndex += 1 + numIds;
        numFaces = numIds - 2;
        numIds = 3;
447
      }
448 449

      for (vtkIdType j = 0; j < numFaces; j++)
450
      {
451 452 453 454 455
        double faceNormal[3];
        vtkPolygon::ComputeNormal(points, numIds, pointIds, faceNormal);

        // For strips, reverse normal of every other triangle
        if ((j & 1) == 1)
456
        {
457 458 459
          faceNormal[0] = -faceNormal[0];
          faceNormal[1] = -faceNormal[1];
          faceNormal[2] = -faceNormal[2];
460
        }
461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476

        // Extra stuff is for calculating the angle
        double vec1[3];
        double vec2[3];
        double p1[3];
        double p2[3];

        points->GetPoint(pointIds[numIds-1], p1);
        points->GetPoint(pointIds[0], p2);
        vec2[0] = p2[0] - p1[0];
        vec2[1] = p2[1] - p1[1];
        vec2[2] = p2[2] - p1[2];
        vtkMath::Normalize(vec2);

        // Go through all points in the face
        for (vtkIdType k = 0; k < numIds; k++)
477
        {
478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496
          vec1[0] = -vec2[0];
          vec1[1] = -vec2[1];
          vec1[2] = -vec2[2];

          p1[0] = p2[0];
          p1[1] = p2[1];
          p1[2] = p2[2];

          points->GetPoint(pointIds[(k+1)%numIds], p2);

          vec2[0] = p2[0] - p1[0];
          vec2[1] = p2[1] - p1[1];
          vec2[2] = p2[2] - p1[2];
          vtkMath::Normalize(vec2);

          // Use dotprod to calculate angle between vectors
          double angle = 0.0;
          double dotprod = vtkMath::Dot(vec1, vec2);
          if (dotprod >= 1.0)
497
          {
498
            angle = 0.0;
499
          }
500
          else if (dotprod <= -1.0)
501
          {
502
            angle = vtkMath::Pi();
503
          }
504
          else
505
          {
506
            angle = acos(dotprod);
507
          }
508 509 510 511 512 513

          // Accumulate contributions of each polygon to the point normals
          float *normal = newNormals->GetPointer(3*pointIds[k]);
          normal[0] += angle*faceNormal[0];
          normal[1] += angle*faceNormal[1];
          normal[2] += angle*faceNormal[2];
514
        }
515 516 517 518

        // Go to next triangle in strip
        pointIds++;
      }
519
    }
520 521

    // Normalize the normals
David Gobbi's avatar
David Gobbi committed
522
    for (vtkIdType jj = 0; jj < numPoints; jj++)
523
    {
David Gobbi's avatar
David Gobbi committed
524
      float *normal = newNormals->GetPointer(3*jj);
525
      vtkMath::Normalize(normal);
526
    }
527 528

    normals = newNormals;
529
  }
530 531 532 533

  int status = this->WriteValues(normals);

  if (newNormals)
534
  {
535
    newNormals->Delete();
536
  }
537 538 539 540 541

  return status;
}

//-------------------------------------------------------------------------
542 543
int vtkMNIObjectWriter::WriteColors(
  vtkProperty *property, vtkMapper *mapper, vtkPolyData *data)
544 545 546 547 548 549
{
  vtkUnsignedCharArray *newScalars = 0;
  vtkDataArray *scalars = data->GetPointData()->GetScalars();
  vtkIdType colorType = 2;

  if (scalars == 0)
550
  {
551 552
    scalars = data->GetCellData()->GetScalars();
    colorType = 1;
553
  }
554

555
  if (this->Mapper)
556
  {
557
    int cellFlag = 0;
558
    scalars = 0;
559

560 561
    // Get color scalars according to Mapper rules
    if (mapper->GetScalarVisibility())
562
    {
563 564 565
      scalars = vtkAbstractMapper::GetScalars(
        data, mapper->GetScalarMode(), mapper->GetArrayAccessMode(),
        mapper->GetArrayId(), mapper->GetArrayName(), cellFlag);
566
    }
567 568 569 570

    // Cell or point scalars?
    colorType = 2;
    if (cellFlag)
571
    {
572
      colorType = 1;
573
    }
574 575 576 577

    // Cannot use cell scalars for triangle strips
    if (cellFlag == 1 && data->GetStrips() &&
        data->GetStrips()->GetNumberOfCells() != 0)
578
    {
579
      scalars = 0;
580
    }
581

582
    if (scalars)
583
    {
584 585
      int arrayComponent = mapper->GetArrayComponent();
      if (scalars->GetNumberOfComponents() <= arrayComponent)
586
      {
587
        arrayComponent = 0;
588
      }
589 590 591

      vtkScalarsToColors *lookupTable = scalars->GetLookupTable();
      if (lookupTable == 0)
592
      {
593 594
        lookupTable = mapper->GetLookupTable();
        lookupTable->Build();
595
      }
596 597

      if (!mapper->GetUseLookupTableScalarRange())
598
      {
599
        lookupTable->SetRange(mapper->GetScalarRange());
600
      }
601 602 603 604 605

      newScalars = lookupTable->MapScalars(
        scalars, mapper->GetColorMode(), arrayComponent);
      scalars = newScalars;
    }
606
  }
607
  else if (scalars != 0)
608
  {
609
    if (this->LookupTable)
610
    {
611 612
      newScalars = this->LookupTable->MapScalars(
        scalars, VTK_COLOR_MODE_MAP_SCALARS, -1);
613
      scalars = newScalars;
614
    }
615
    else if (scalars->GetDataType() != VTK_UNSIGNED_CHAR)
616
    {
617 618
      scalars = 0;
    }
619
  }
620 621

  if (scalars == 0)
622
  {
623 624 625 626 627 628
    colorType = 0;

    newScalars = vtkUnsignedCharArray::New();
    newScalars->SetNumberOfComponents(4);
    newScalars->SetNumberOfTuples(1);

David Gobbi's avatar
David Gobbi committed
629 630 631
    unsigned char rgba[4];

    if (property)
632
    {
633
      double color[3];
David Gobbi's avatar
David Gobbi committed
634 635
      property->GetColor(color);
      double opacity = property->GetOpacity();
636 637 638 639 640

      rgba[0] = static_cast<unsigned char>(color[0]*255);
      rgba[1] = static_cast<unsigned char>(color[1]*255);
      rgba[2] = static_cast<unsigned char>(color[2]*255);
      rgba[3] = static_cast<unsigned char>(opacity*255);
641
    }
642
    else
643
    {
644 645 646 647
      rgba[0] = 255;
      rgba[1] = 255;
      rgba[2] = 255;
      rgba[3] = 255;
648
    }
649

David C. Lonie's avatar
David C. Lonie committed
650
    newScalars->SetTypedTuple(0, rgba);
651
    scalars = newScalars;
652
  }
653 654 655 656

  int status = this->WriteIdValue(colorType);

  if (status != 0)
657
  {
658
    status = this->WriteValues(scalars);
659
  }
660 661

  if (newScalars)
662
  {
663
    newScalars->Delete();
664
  }
665 666 667 668 669 670 671 672 673

  return status;
}

//-------------------------------------------------------------------------
int vtkMNIObjectWriter::WriteCells(vtkPolyData *data, int cellType)
{
  vtkCellArray *cellArray = 0;
  if (cellType == VTK_POLYGON)
674
  {
675
    cellArray = data->GetPolys();
676
  }
677
  else if (cellType == VTK_POLY_LINE)
678
  {
679
    cellArray = data->GetLines();
680
  }
681
  else
682
  {
683
    return 0;
684
  }
685 686 687 688 689

  vtkIntArray *endIndices = vtkIntArray::New();
  vtkIntArray *cellIndices = vtkIntArray::New();

  if (cellArray)
690
  {
691 692 693 694 695 696 697 698 699 700
    vtkIdType numCells = cellArray->GetNumberOfCells();
    vtkIdType numCellIndices = (cellArray->GetNumberOfConnectivityEntries()
                                - numCells);

    endIndices->Allocate(numCells);
    cellIndices->Allocate(numCellIndices);

    vtkIdType cellIndex = 0;
    vtkIdType endIndex = 0;
    for (vtkIdType i = 0; i < numCells; i++)
701
    {
702 703 704 705 706 707 708 709
      vtkIdType *pointIds;
      vtkIdType numIds;
      cellArray->GetCell(cellIndex, numIds, pointIds);
      cellIndex += 1 + numIds;

      endIndex += numIds;
      endIndices->InsertNextValue(endIndex);
      for (vtkIdType j = 0; j < numIds; j++)
710
      {
711 712 713
        cellIndices->InsertNextValue(pointIds[j]);
      }
    }
714
  }
715 716 717

  // Convert triangle strips to triangles
  if (cellType == VTK_POLYGON && data->GetNumberOfStrips() != 0)
718
  {
719 720 721 722 723 724
    cellArray = data->GetStrips();
    vtkIdType numCells = cellArray->GetNumberOfCells();

    vtkIdType cellIndex = 0;
    vtkIdType endIndex = 0;
    if (endIndices->GetMaxId() >= 0)
725
    {
726
      endIndex = endIndices->GetValue(endIndices->GetMaxId());
727
    }
728
    for (vtkIdType i = 0; i < numCells; i++)
729
    {
730 731 732 733 734 735 736 737
      vtkIdType *pointIds;
      vtkIdType numIds;
      cellArray->GetCell(cellIndex, numIds, pointIds);
      cellIndex += 1 + numIds;

      int inc1 = 2;
      int inc2 = 1;
      for (vtkIdType j = 2; j < numIds; j++)
738
      {
739 740 741 742 743 744 745 746 747 748 749 750 751
        endIndex += 3;
        endIndices->InsertNextValue(endIndex);

        cellIndices->InsertNextValue(pointIds[j-inc1]);
        cellIndices->InsertNextValue(pointIds[j-inc2]);
        cellIndices->InsertNextValue(pointIds[j]);

        // reverse the order each time around
        int tmp = inc1;
        inc1 = inc2;
        inc2 = tmp;
      }
    }
752
  }
753 754 755 756 757 758

  // Write the cell end indices
  int status = this->WriteValues(endIndices);

  // Write the newline
  if (status != 0)
759
  {
760
    status = this->WriteNewline();
761
  }
762 763 764

  // Write the cell point indices
  if (status != 0)
765
  {
766
    status = this->WriteValues(cellIndices);
767
  }
768 769 770 771 772 773 774 775 776 777 778 779

  endIndices->Delete();
  cellIndices->Delete();

  return status;
}

//-------------------------------------------------------------------------
int vtkMNIObjectWriter::WritePolygonObject(vtkPolyData *output)
{
  // Write the surface property
  if (this->WriteProperty(this->Property) == 0)
780
  {
781
    return 0;
782
  }
783 784 785

  // Write the number of points
  if (this->WriteIdValue(output->GetNumberOfPoints()) == 0)
786
  {
787
    return 0;
788
  }
789 790 791

  // Write a newline
  if (this->WriteNewline() == 0)
792
  {
793
    return 0;
794
  }
795 796 797

  // Write the points
  if (this->WritePoints(output) == 0)
798
  {
799
    return 0;
800
  }
801 802 803

  // Write a newline
  if (this->WriteNewline() == 0)
804
  {
805
    return 0;
806
  }
807 808 809

  // Write the normals
  if (this->WriteNormals(output) == 0)
810
  {
811
    return 0;
812
  }
813 814 815

  // Write a newline
  if (this->WriteNewline() == 0)
816
  {
817
    return 0;
818
  }
819 820 821 822 823

  // Write the number of items
  vtkIdType numPolys = output->GetNumberOfPolys();
  vtkIdType numStrips = output->GetNumberOfStrips();
  if (numStrips > 0)
824
  {
825 826
    numPolys += (output->GetStrips()->GetNumberOfConnectivityEntries()
                 - 3*numStrips);
827
  }
828
  if (this->WriteIdValue(numPolys) == 0)
829
  {
830
    return 0;
831
  }
832 833 834

  // Write a newline
  if (this->WriteNewline() == 0)
835
  {
836
    return 0;
837
  }
838 839

  // Write the colors
840
  if (this->WriteColors(this->Property, this->Mapper, output) == 0)
841
  {
842
    return 0;
843
  }
844 845 846

  // Write a newline
  if (this->WriteNewline() == 0)
847
  {
848
    return 0;
849
  }
850 851 852

  // Write the cells
  if (this->WriteCells(output, VTK_POLYGON) == 0)
853
  {
854
    return 0;
855
  }
856 857 858

  // Write a newline
  if (this->WriteNewline() == 0)
859
  {
860
    return 0;
861
  }
862 863 864 865 866 867 868 869 870

  return 1;
}

//-------------------------------------------------------------------------
int vtkMNIObjectWriter::WriteLineObject(vtkPolyData *output)
{
  // Write the surface property
  if (this->WriteLineThickness(this->Property) == 0)
871
  {
872
    return 0;
873
  }
874 875 876

  // Write the number of points
  if (this->WriteIdValue(output->GetNumberOfPoints()) == 0)
877
  {
878
    return 0;
879
  }
880 881 882

  // Write a newline
  if (this->WriteNewline() == 0)
883
  {
884
    return 0;
885
  }
886 887 888

  // Write the points
  if (this->WritePoints(output) == 0)
889
  {
890
    return 0;
891
  }
892 893 894

  // Write a newline
  if (this->WriteNewline() == 0)
895
  {
896
    return 0;
897
  }
898 899 900

  // Write the number of items
  if (this->WriteIdValue(output->GetNumberOfLines()) == 0)
901
  {
902
    return 0;
903
  }
904 905 906

  // Write a newline
  if (this->WriteNewline() == 0)
907
  {
908
    return 0;
909
  }
910 911

  // Write the colors
912
  if (this->WriteColors(this->Property, this->Mapper, output) == 0)
913
  {
914
    return 0;
915
  }
916 917 918

  // Write a newline
  if (this->WriteNewline() == 0)
919
  {
920
    return 0;
921
  }
922 923

  // Write the cells
924
  if (this->WriteCells(output, VTK_POLY_LINE) == 0)
925
  {
926
    return 0;
927
  }
928 929 930

  // Write a newline
  if (this->WriteNewline() == 0)
931
  {
932
    return 0;
933
  }
934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949

  return 1;
}

//-------------------------------------------------------------------------
void vtkMNIObjectWriter::WriteData()
{
  vtkPolyData *input = this->GetInput();
  int objType = 0;

  vtkIdType npolys = input->GetNumberOfPolys();
  vtkIdType nstrips = input->GetNumberOfStrips();
  vtkIdType nlines = input->GetNumberOfLines();
  vtkIdType nverts = input->GetNumberOfVerts();

  if (nverts != 0)
950
  {
951 952
    vtkErrorMacro("Unable to write vertexes.");
    return;
953
  }
954 955

  if ((npolys != 0 || nstrips != 0) && nlines != 0)
956
  {
957 958
    vtkErrorMacro("Unable to write a data set with multiple cell types.");
    return;
959
  }
960 961

  if (npolys != 0 || nstrips != 0)
962
  {
963
    objType = 'P';
964
  }
965
  else if (nlines != 0)
966
  {
967
    objType = 'L';
968
  }
969 970

  // Open the file
971
  this->OutputStream = this->OpenFile();
972

973
  if (!this->OutputStream)
974
  {
975
    return;
976
  }
977

978 979 980 981 982
  // Write the type character
  this->WriteObjectType(objType);

  // Write the object
  switch(objType)
983
  {
984 985 986 987 988 989
    case 'P':
      this->WritePolygonObject(input);
      break;
    case 'L':
      this->WriteLineObject(input);
      break;
990
  }
991 992

  // Close the file
993
  this->CloseFile(this->OutputStream);
994 995 996

  // Delete the file if an error occurred
  if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
997
  {
998 999 1000
    vtkErrorMacro("Ran out of disk space; deleting file: "
                  << this->FileName);
    unlink(this->FileName);
1001
  }
1002
}
1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029


//-------------------------------------------------------------------------
vtkPolyData* vtkMNIObjectWriter::GetInput()
{
  return vtkPolyData::SafeDownCast(this->Superclass::GetInput());
}

//-------------------------------------------------------------------------
vtkPolyData* vtkMNIObjectWriter::GetInput(int port)
{
  return vtkPolyData::SafeDownCast(this->Superclass::GetInput(port));
}

//-------------------------------------------------------------------------
int vtkMNIObjectWriter::FillInputPortInformation(int, vtkInformation *info)
{
  info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkPolyData");
  return 1;
}

//-------------------------------------------------------------------------
ostream *vtkMNIObjectWriter::OpenFile()
{
  ostream *fptr;

  if (!this->FileName )
1030
  {
1031 1032 1033
    vtkErrorMacro(<< "No FileName specified! Can't write!");
    this->SetErrorCode(vtkErrorCode::NoFileNameError);
    return NULL;
1034
  }
1035 1036 1037 1038

  vtkDebugMacro(<<"Opening file for writing...");

  if ( this->FileType == VTK_ASCII )
1039
  {
1040
    fptr = new ofstream(this->FileName, ios::out);
1041
  }
Berk Geveci's avatar