File ( const TCHAR *name, const TCHAR *mode) { // for a360 support - allows binary diff syncing if (mode != nullptr && (mode[0] == _T('w') || mode[0] == _T('a') || (mode[0] == _T('r') && mode[1] == _T('+') ))) { MaxSDK::Util::Path storageNamePath(name); storageNamePath.SaveBaseFile(); } stream = _tfopen(name,mode); }
void PrettyPrint(const TCHAR* name, CComPtr<IXMLDOMDocument> pXMLDoc) { // perform formatting XSLT transform to get indented XML output CComPtr<IXMLDOMDocument> pXSLDoc; BSTR outputXML = NULL; HRESULT hr = CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, IID_IXMLDOMDocument, (void**)&pXSLDoc); if (SUCCEEDED(hr)) { // load indenting XSL doc VARIANT_BOOL result; CComBSTR indentXSL( "<xsl:stylesheet version=\"1.0\"" " xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">" " <xsl:output method=\"xml\"/>" " <xsl:param name=\"indent-increment\" select=\"'\t'\" />" " <xsl:template match=\"node()\">" " <xsl:param name=\"indent\" select=\"'
'\"/>" " <xsl:value-of select=\"$indent\"/>" " <xsl:copy>" " <xsl:copy-of select=\"@*\" />" " <xsl:apply-templates>" " <xsl:with-param name=\"indent\"" " select=\"concat($indent, $indent-increment)\"/>" " </xsl:apply-templates>" " <xsl:if test=\"node()\">" " <xsl:value-of select=\"$indent\"/>" " </xsl:if>" " </xsl:copy>" " </xsl:template>" // " <xsl:template match=\"comment()|processing-instruction()\">" // " <xsl:copy />" // " </xsl:template>" // " <!-- WARNING: this is dangerous. Handle with care -->" // " <xsl:template match=\"text()[normalize-space(.)='']\"/>" "</xsl:stylesheet>" ); hr = pXSLDoc->loadXML(indentXSL, &result); if (SUCCEEDED(hr)) { // perform transform hr = pXMLDoc->transformNode(pXSLDoc, &outputXML); } } // output transformed XML if previous sequence succeeded, else normal XMLDoc save if (SUCCEEDED(hr)) { MaxSDK::Util::TextFile::Writer out; //Need UTF8 if (out.Open(name, false, CP_UTF8)) { // hack the UTF-16 back to UTF-8 (there probably is a way to mod the stylesheet to do this) wchar_t* enc = wcsstr(outputXML, L"\"UTF-16\""); if (enc != NULL) memcpy(enc, L"\"utf-8\" ", 8 * sizeof(wchar_t)); // convert BSTR to MBCS for output // write the XML out.Write(outputXML); out.Close(); } SysFreeString(outputXML); } else { // for a360 support - allows binary diff syncing MaxSDK::Util::Path storageNamePath(name); storageNamePath.SaveBaseFile(); // save the XML graph out to the export file pXMLDoc->save(CComVariant(name)); } }
int Blockporter::DoExport(const TCHAR* name, ExpInterface* ei, Interface* i, BOOL supressPrompts, DWORD options) { INode* root; //caption and message for MessagesBoxes TCHAR msg[MB_BUFFER_LENGTH]; TCHAR cap[MB_BUFFER_LENGTH]; //Get the root node root = i->GetRootNode(); //the node of our object should be a groupnode, which contains every object //we want to export i->PushPrompt(_T("Searching for Group...")); bool found = false; for(int idx = 0; idx < root->NumberOfChildren(); idx++) { if(root->GetChildNode(idx)->IsGroupHead()) { //we found our group //next step is to make the group node our new root, because every object //we want is part of this group found = true; root = root->GetChildNode(idx); break; } } if(!found) { MessageBox(nullptr, GetString(IDS_ERROR_NO_GROUP, msg), GetString(IDS_GENERAL_ERROR, cap), MB_OK | MB_ICONERROR); return 0; } //Now that we have the groupnode let's compare the fileversions if(!IsNewModelVersion(name, root->GetName())) { if(MessageBox(nullptr, GetString(IDS_VER_TO_LOW_MSG, msg), GetString(IDS_VER_TO_LOW_CAP, cap), MB_YESNO | MB_ICONEXCLAMATION) == IDNO) return 1; } i->PushPrompt(_T("Opening File")); Interface14* iface = GetCOREInterface14(); UINT code = iface->DefaultTextSaveCodePage(true); MaxSDK::Util::Path storageNamePath(name); storageNamePath.SaveBaseFile(); switch (code & MaxSDK::Util::MaxStringDataEncoding::MSDE_CP_MASK) { case CP_UTF8: mStream = _tfopen(name, _T("wt, ccs=UFT-8")); break; case MaxSDK::Util::MaxStringDataEncoding::MSDE_CP_UTF16: mStream = _tfopen(name, _T("wt, ccs=UTF-16BE")); break; default: mStream = _tfopen(name, _T("wt")); } if(!mStream) return 0; //now we have our file stream, so let's write the header i->PushPrompt(_T("Writing Header")); WriteHeader(root->GetName(), root->NumberOfChildren()); //now that we have the header written, let's iterate through the objects in the //group and export the meshes and lights INode* child; Point3 pMin(0,0,0), pMax(0,0,0); for(int idx = 0; idx < root->NumberOfChildren(); idx++) { child = root->GetChildNode(idx); i->PushPrompt(_T("Processing Object %s", child->GetName())); if(child->IsGroupHead()) { MessageBox(nullptr, GetString(IDS_ERROR_TO_MANY_GROUPS, msg), GetString(IDS_GENERAL_ERROR, cap), MB_OK | MB_ICONERROR); continue; } ObjectState os = child->EvalWorldState(0); //let's take a look at the SuperClassID of the object //so we find out if it's a mesh or a light if(!os.obj) continue; //somehow this node doesn't have an object Box3 boundBox; switch(os.obj->SuperClassID()) { case GEOMOBJECT_CLASS_ID: _ftprintf(mStream, _T("<ObjectID=%i>\n"), idx); i->PushPrompt(_T("Writing MeshData for Object %s", child->GetName())); boundBox = WriteMeshData(child, idx); pMin.x = (boundBox.Min().x < pMin.x) ? boundBox.Min().x : pMin.x; pMin.y = (boundBox.Min().y < pMin.y) ? boundBox.Min().y : pMin.y; pMax.x = (boundBox.Max().x > pMax.x) ? boundBox.Max().x : pMax.x; pMax.y = (boundBox.Max().y > pMax.y) ? boundBox.Max().y : pMax.y; i->PushPrompt(_T("Writing MaterialData for Object %s", child->GetName())); WriteMaterialData(child); _ftprintf(mStream, _T("</Object>\n")); break; //case LIGHT_CLASS_ID: // WriteLightData(child, idx); // break; } } //Write the Bounding Box _ftprintf(mStream, _T("<BoundingBox>\n")); _ftprintf(mStream, _T("\t<Min=%f,%f>\n"), pMin.x, pMin.y); _ftprintf(mStream, _T("\t<Max=%f,%f>\n"), pMax.x, pMax.y); _ftprintf(mStream, _T("</BoundingBox>\n")); //we are done exporting, so close the stream i->PushPrompt(_T("Closing file...")); fclose(mStream); MessageBox(nullptr, GetString(IDS_FINISH_MSG, msg), GetString(IDS_FINISH_CAP, cap), MB_OK | MB_ICONINFORMATION); return 1; }
/* This function handles writing out EPS files. It is written to be * as "PostScript friendly as possible", i.e. it: * 1) Uses a fairly full set of DSC comments * 2) Uses its own dictionary instead of assuming there is room in * the current one * 3) If colorimage is not supported on the PostScript interpreter * and an RGB image was selected the image will be rendered as grayscale * instead using the NTSC conversion. */ BMMRES BitmapIO_EPS::Save(const TCHAR *name, Bitmap *bitmap) { int xOffset = 0; // Offset for the lower left corner int yOffset = 0; // of the image */ int status; if (! bitmap) return (ProcessImageIOError(&bi,BMMRES_INTERNALERROR)); /* Compute the position on the page to output the image */ Position (bitmap, &xOffset, &yOffset); // for a360 support - allows binary diff syncing MaxSDK::Util::Path storageNamePath(name); storageNamePath.SaveBaseFile(); if ((mOutStream = _tfopen(name, _T("wb"))) == NULL) return (ProcessImageIOError(&bi)); /* If a preview is desired then write the TIFF section */ if (userSettings.preview) { status = WritePreview (userSettings.colorType, userSettings.orientation, userSettings.xResolution, userSettings.yResolution, bitmap); if (status != BMMRES_SUCCESS) { fclose (mOutStream); return status; } } /* First the PostScript header */ status = WriteHeader (bitmap, xOffset, yOffset); if (status != BMMRES_SUCCESS) { fclose (mOutStream); return status; } /* Now the image data itself */ status = WriteImagePosition (bitmap, xOffset, yOffset); if (status != BMMRES_SUCCESS) { fclose (mOutStream); return status; } if (userSettings.binary && userSettings.colorType == RGBIMAGE) status = WriteBinaryRGBImage (bitmap); else if (userSettings.binary && userSettings.colorType == GRAYIMAGE) status = WriteBinaryGrayImage (bitmap); else if (userSettings.colorType == RGBIMAGE) status = WriteAsciiRGBImage (bitmap); else status = WriteAsciiGrayImage (bitmap); if (status != BMMRES_SUCCESS) { fclose (mOutStream); return status; } /* Now the trailer */ status = WriteTrailer (); /* If a preview was requested we need to now figure out the length of the * PostScript portion and write it to the header */ if (userSettings.preview) status = WritePSLength (userSettings.colorType, map); fclose (mOutStream); return (status); }
BMMRES BitmapIO_PNG::Save(const TCHAR *filename, Bitmap *map) { if(!map) return(ProcessImageIOError(&bi,BMMRES_INTERNALERROR)); openMode = BMM_OPEN_W; // for a360 support - allows binary diff syncing MaxSDK::Util::Path storageNamePath(filename); storageNamePath.SaveBaseFile(); if((mOutStream = _tfopen(filename,_T("wb"))) == NULL) return (ProcessImageIOError(&bi)); BitmapStorage *palettedStorage = NULL; png = png_create_write_struct (PNG_VERSION, (void *) this, error_func, warning_func); if (setjmp(png->jmpbuf)) { if (info) for (png_uint_32 i = 0; i < info->height; i++) if (row_pointers[i]) free(row_pointers[i]); if (row_pointers) { free(row_pointers); row_pointers = NULL; } if (palettedStorage) delete palettedStorage; fclose(mOutStream); _tremove(filename); png_destroy_write_struct (&png, &info); return BMMRES_IOERROR; } info = png_create_info_struct(png); png_init_io(png, mOutStream); switch(cfg.color_type) { case PngPalette: info->color_type = PNG_COLOR_TYPE_PALETTE; info->pixel_depth = 8; info->valid |= PNG_INFO_PLTE; info->num_palette = 256; break; case PngRGB: info->color_type = PNG_COLOR_TYPE_RGB; break; case PngRGBA: info->color_type = PNG_COLOR_TYPE_RGB_ALPHA; break; case PngGray: info->color_type = PNG_COLOR_TYPE_GRAY; break; case PngGrayA: info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA; break; } info->width = map->Width(); info->height = map->Height(); // If gamma is on - store this in the file if (gammaMgr.enable) { info->valid |= PNG_INFO_gAMA; info->gamma = 1.0 / OutputGamma(); } else info->gamma = 1.0f; if (map->Aspect() != 1.0f) { info->valid |= PNG_INFO_pHYs; info->x_pixels_per_unit = (png_uint_32)(1024.0f * map->Aspect()); info->y_pixels_per_unit = 1024; info->phys_unit_type = 0; } if (cfg.interlaced) info->interlace_type = 1; else info->interlace_type = 0; switch( info->color_type) { case PNG_COLOR_TYPE_PALETTE: case PNG_COLOR_TYPE_GRAY: info->channels = 1; break; case PNG_COLOR_TYPE_GRAY_ALPHA: info->channels = 2; break; case PNG_COLOR_TYPE_RGB: info->channels = 3; break; case PNG_COLOR_TYPE_RGB_ALPHA: info->channels = 4; break; } info->bit_depth = cfg.bitdepth; info->rowbytes = info->width * info->channels * info->bit_depth / 8; row_pointers = (png_bytep *)malloc(info->height * sizeof(png_bytep)); for (png_uint_32 i = 0; i < info->height; i++) row_pointers[i] = (png_bytep)malloc(info->rowbytes); switch (info->bit_depth) { case 16: // this is only RGB/RGBA/Gray/GrayA switch(info->color_type) { case PNG_COLOR_TYPE_RGB: case PNG_COLOR_TYPE_RGB_ALPHA: { // [dl | 22feb2005] Use a BMM_Color_fl buffer because the BMM_Color_64 version of GetOutputPixels() // uses a 13bit lookup table to do gamma correction, thus clamping the values. BMM_Color_fl *line_fl = (BMM_Color_fl *) calloc(info->width,sizeof(BMM_Color_fl)); for (png_uint_32 iy = 0; iy < info->height; ++iy) { if (GetOutputPixels(0, iy, info->width, line_fl) != 1) { for (png_uint_32 i = 0; i < info->height; i++) if (row_pointers[i]) free(row_pointers[i]); if (row_pointers) { free(row_pointers); row_pointers = NULL; } fclose(mOutStream); _tremove(filename); free(line_fl); png_destroy_write_struct (&png, &info); return BMMRES_IOERROR; } BMM_Color_fl *l_fl=line_fl; unsigned short *oshort = (unsigned short *)row_pointers[iy]; for (png_uint_32 ix = 0; ix < info->width; ++l_fl, ix++) { *oshort = BMM_Color_fl::clipColor(l_fl->r); oshort++; *oshort = BMM_Color_fl::clipColor(l_fl->g); oshort++; *oshort = BMM_Color_fl::clipColor(l_fl->b); oshort++; if (info->channels == 4) { *oshort = BMM_Color_fl::clipColor(l_fl->a); oshort++; } } } free(line_fl); } break; case PNG_COLOR_TYPE_GRAY: { // [dl | 22feb2005] Use a float buffer because the BMM_Color_64 version of GetOutputPixels() // uses a 13bit lookup table to do gamma correction, thus clamping the values. float *line_fl_gray = (float*) calloc(info->width, sizeof(float)); for (png_uint_32 iy = 0; iy < info->height; ++iy) { if (map->Get16Gray(0, iy, info->width, line_fl_gray) != 1) { for (png_uint_32 i = 0; i < info->height; i++) if (row_pointers[i]) free(row_pointers[i]); if (row_pointers) { free(row_pointers); row_pointers = NULL; } free(line_fl_gray); fclose(mOutStream); _tremove(filename); png_destroy_write_struct (&png, &info); return BMMRES_IOERROR; } float *l_fl_gray=line_fl_gray; unsigned short *oshort = (unsigned short *)row_pointers[iy]; for (png_uint_32 ix = 0; ix < info->width; ix++, l_fl_gray++) { *oshort++ = BMM_Color_fl::clipColor(*l_fl_gray); } } free(line_fl_gray); } break; case PNG_COLOR_TYPE_GRAY_ALPHA: { // [dl | 22feb2005] Use a BMM_Color_fl buffer because the BMM_Color_64 version of GetOutputPixels() // uses a 13bit lookup table to do gamma correction, thus clamping the values. BMM_Color_fl *line_fl = (BMM_Color_fl *) calloc(info->width, sizeof(BMM_Color_fl)); float *line_fl_gray = (float*) calloc(info->width, sizeof(float)); for (png_uint_32 iy = 0; iy < info->height; ++iy) { if (GetOutputPixels(0, iy, info->width, line_fl) != 1 || map->Get16Gray(0, iy, info->width, line_fl_gray) != 1) { for (png_uint_32 i = 0; i < info->height; i++) if (row_pointers[i]) free(row_pointers[i]); if (row_pointers) { free(row_pointers); row_pointers = NULL; } free(line_fl); free(line_fl_gray); fclose(mOutStream); _tremove(filename); png_destroy_write_struct (&png, &info); return BMMRES_IOERROR; } BMM_Color_fl *l_fl = line_fl; float *l_fl_gray=line_fl_gray; unsigned short *oshort = (unsigned short *)row_pointers[iy]; for (png_uint_32 ix = 0; ix < info->width; ix++, l_fl++, l_fl_gray++) { *oshort++ = BMM_Color_fl::clipColor(*l_fl_gray); *oshort++ = BMM_Color_fl::clipColor(l_fl->a); } } free(line_fl); free(line_fl_gray); } break; } break; case 8: // this can be any type switch(info->color_type) { case PNG_COLOR_TYPE_PALETTE: { // Set up a palette buffer PixelBuf48 palettebuf(info->num_palette); BMM_Color_48 *pal = palettebuf.Ptr(); // Must compute a color palette, and reduce the image to 256 colors! // this calculates a palette based on the gamma corrected values, which // corresponds to what GetOutputPixels returns. if(CalcOutputPalette(256, pal) == 0) { for (png_uint_32 i = 0; i < info->height; i++) if (row_pointers[i]) free(row_pointers[i]); if (row_pointers) { free(row_pointers); row_pointers = NULL; } fclose(mOutStream); _tremove(filename); png_destroy_write_struct (&png, &info); return BMMRES_IOERROR; } info->palette = (png_color *)malloc(info->num_palette * sizeof(png_color)); for (int i = 0; i < info->num_palette; i++) { info->palette[i].red = (unsigned char)(pal[i].r >> 8); info->palette[i].green = (unsigned char)(pal[i].g >> 8); info->palette[i].blue = (unsigned char)(pal[i].b >> 8); } PixelBuf64 line(info->width); ColorPacker* cpack = BMMNewColorPacker(info->width, pal, info->num_palette); for (png_uint_32 iy=0; iy < info->height; ++iy) { if(!GetOutputPixels(0, iy, info->width, line.Ptr())) { for (png_uint_32 i = 0; i < info->height; i++) if (row_pointers[i]) free(row_pointers[i]); if (row_pointers) { free(row_pointers); row_pointers = NULL; } fclose(mOutStream); _tremove(filename); png_destroy_write_struct (&png, &info); return BMMRES_IOERROR; } cpack->PackLine(line.Ptr(), row_pointers[iy], info->width); } cpack->DeleteThis(); } break; case PNG_COLOR_TYPE_RGB: case PNG_COLOR_TYPE_RGB_ALPHA: { BMM_Color_32 *line32 = (BMM_Color_32 *) calloc(info->width,sizeof(BMM_Color_32)); for (png_uint_32 iy = 0; iy < info->height; ++iy) { if (GetDitheredOutputPixels(0, iy, info->width, line32) != 1) { for (png_uint_32 i = 0; i < info->height; i++) if (row_pointers[i]) free(row_pointers[i]); if (row_pointers) { free(row_pointers); row_pointers = NULL; } fclose(mOutStream); _tremove(filename); free(line32); png_destroy_write_struct (&png, &info); return BMMRES_IOERROR; } BMM_Color_32 *l32=line32; unsigned char *obyte = (unsigned char *)row_pointers[iy]; for (png_uint_32 ix = 0; ix < info->width; ++l32, ix++) { *obyte = (unsigned char)l32->r; obyte++; *obyte = (unsigned char)l32->g; obyte++; *obyte = (unsigned char)l32->b; obyte++; if (info->channels == 4) { *obyte = (unsigned char)l32->a; obyte++; } } } free(line32); } break; case PNG_COLOR_TYPE_GRAY: { unsigned short *line = (unsigned short *) calloc(info->width * info->channels, sizeof(unsigned short)); for (png_uint_32 iy = 0; iy < info->height; ++iy) { if (map->Get16Gray(0, iy, info->width, line) != 1) { for (png_uint_32 i = 0; i < info->height; i++) if (row_pointers[i]) free(row_pointers[i]); if (row_pointers) { free(row_pointers); row_pointers = NULL; } fclose(mOutStream); _tremove(filename); free(line); png_destroy_write_struct (&png, &info); return BMMRES_IOERROR; } unsigned short *l=line; unsigned char *obyte = (unsigned char *)row_pointers[iy]; for (png_uint_32 ix = 0; ix < info->width; ix++) { *obyte++ = (unsigned char)(*l >> 8); l++; } } free(line); } break; case PNG_COLOR_TYPE_GRAY_ALPHA: { BMM_Color_64 *line64 = (BMM_Color_64 *) calloc(info->width,sizeof(BMM_Color_64)); unsigned short *line = (unsigned short *) calloc(info->width, sizeof(unsigned short)); for (png_uint_32 iy = 0; iy < info->height; ++iy) { if (GetOutputPixels(0, iy, info->width, line64) != 1 || map->Get16Gray(0, iy, info->width, line) != 1) { for (png_uint_32 i = 0; i < info->height; i++) if (row_pointers[i]) free(row_pointers[i]); if (row_pointers) { free(row_pointers); row_pointers = NULL; } fclose(mOutStream); _tremove(filename); free(line); free(line64); png_destroy_write_struct (&png, &info); return BMMRES_IOERROR; } unsigned short *l=line; BMM_Color_64 *l64 = line64; unsigned char *obyte = (unsigned char *)row_pointers[iy]; for (png_uint_32 ix = 0; ix < info->width; ix++, l64++) { *obyte++ = (unsigned char)(*l >> 8); l++; *obyte++ = (unsigned char)(l64->a >> 8); } } free(line); free(line64); } break; } break; #ifdef OUTPUT_1_2_4 case 4: { // Paletted only } break; case 2: { // Paletted only } break; case 1: { // Paletted only } #endif break; } png_write_info(png, info); png_set_swap(png); png_write_image(png, row_pointers); png_write_end(png, info); fclose(mOutStream); for (png_uint_32 i = 0; i < info->height; i++) free(row_pointers[i]); free(row_pointers); png_destroy_write_struct (&png, &info); return BMMRES_SUCCESS; }