GrpcPrint/PrintS/job/JobMetaData.cpp
2024-03-26 10:33:00 +08:00

1185 lines
40 KiB
C++

#include "JobMetaData.h"
#include "../utils/CryptHelper.h"
#include <openssl/evp.h>
#include "../external/minizip/zlib.h"
#include <regex>
#include "../LanguageManager.h"
#include "JobController.h"
JobMetaData::JobMetaData()
: m_job_content(NULL)
, m_Parser(NULL)
{
m_Parser = XML_ParserCreate(NULL);
XML_SetElementHandler(m_Parser, StartElement, EndElement);
XML_SetCharacterDataHandler(m_Parser, DataHandler);
}
JobMetaData::~JobMetaData()
{
}
bool JobMetaData::LoadFile(string path, string filename, vector<BPBinary::BFileInfo>& bfileinfos,string binPath)
{
JobContent::EncryptionStrategy* es = m_job_content->m_container_content->encryption_strategies[m_job_content->m_container_content->container_files->metadata_file->encryption_strategy_ref];
string strfilepath = "";
bool isenc = false;
if (es->method=="AES-256_SessionKey") {
JobContent::EncryptedContent* ec = es->session_key->encrypted_contents_map["PreSharedPassPhrase"];
string strPreIV = ec->initialization_vector;
string strPreCTAndTag = ec->cipher_text;
string strRefIV = es->initialization_vector;
string strPassphrase = "SGFuQmFuZ0AyMDE1LjA2LjA0LjAwMSojAAAAAAAAAAB=";
/*string strPreIV = "aksfK19LahxWS1dcKFROEw==";
string strPreCTAndTag ="3jmzVYVaeuhPcEgRbQGg7xnK8s0T016Zm8UhwrBUatKQZgnCGXlpGKcvHcPeN1fY";
string strRefIV = "JwplVTNuRA4PVmcuJDR5Hw==";
string strPassphrase = "VGhpc0lzTXlTYWZlUGFzc3dvcmQ0MgAAAAAAAAAAAAB=";*/
unsigned char* preIV = NULL;
int preIVLength = CryptHelper::Base64DecodeWrap(strPreIV, &preIV);
unsigned char* preCTAndTag = NULL;
int preCTAndTagLength = CryptHelper::Base64DecodeWrap(strPreCTAndTag, &preCTAndTag);
unsigned char* preCT = new unsigned char[preCTAndTagLength - 16];
memcpy(preCT, preCTAndTag, preCTAndTagLength - 16);
unsigned char* preTag = new unsigned char[16];
memcpy(preTag, &preCTAndTag[preCTAndTagLength - 16], 16);
unsigned char* passphrase = NULL;
int passphraseLength = CryptHelper::Base64DecodeWrap(strPassphrase, &passphrase);
unsigned char* sessionKey;
int sessionKeyLength = CryptHelper::AesDecode(preCT, preCTAndTagLength - 16, passphrase, passphraseLength, preIV, preIVLength, preTag, 16, &sessionKey);
unsigned char* refIV = NULL;
int refIVLength = CryptHelper::Base64DecodeWrap(strRefIV, &refIV);
char buffer[1024];
sprintf_s(buffer, sizeof(buffer), "%s\\%s", path.c_str(), filename.c_str());
fstream cipherMetaDataFile;
ifstream sourceMeataDataFile;
sourceMeataDataFile.open(buffer, ios::in | ios::binary);
sourceMeataDataFile.seekg(-16, ios::end);
unsigned char metaTag[16];
sourceMeataDataFile.read((char*)metaTag, 16);
sourceMeataDataFile.seekg(0, ios::beg);
sourceMeataDataFile.seekg(0, ios::end);
int64_t fileSize = sourceMeataDataFile.tellg();
fileSize -= 16;
sourceMeataDataFile.seekg(0, ios::beg);
sprintf_s(buffer, sizeof(buffer), "%s\\temp%s", path.c_str(), filename.c_str());
string encryptfile(buffer);
cipherMetaDataFile.open(encryptfile.c_str(), ios::trunc | ios::out | ios::in | ios::binary);
int64_t readSize = 0;
unsigned char* cleatOut=new unsigned char[2046 * 10];
unsigned int zipOutLength = 2046 * 1000;
unsigned char* zipOut = new unsigned char[zipOutLength];
unsigned char readBuffer[1025 * 10];
unsigned int outLength;
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL);
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, refIVLength, NULL);
EVP_DecryptInit_ex(ctx, NULL, NULL, sessionKey, refIV);
int ret;
z_stream strm;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit2(&strm, -MAX_WBITS);
while (!sourceMeataDataFile.eof() && (readSize< fileSize)) {
int64_t temp = fileSize - readSize;
if (temp > sizeof(readBuffer)) {
sourceMeataDataFile.read((char*)readBuffer, sizeof(readBuffer));
readSize += sizeof(readBuffer);
EVP_DecryptUpdate(ctx, cleatOut, (int*)&outLength, readBuffer, sizeof(readBuffer));
strm.avail_in = outLength;
strm.next_in = cleatOut;
strm.avail_out = zipOutLength;
strm.next_out = zipOut;
ret = inflate(&strm, Z_FINISH);
int deLength = zipOutLength - strm.avail_out;
cipherMetaDataFile.write((char*)zipOut, deLength);
}
else {
sourceMeataDataFile.read((char*)readBuffer, temp);
EVP_DecryptUpdate(ctx, cleatOut, (int*)&outLength, readBuffer, (int)temp);
strm.avail_in = outLength; // size of input, string + terminator
strm.next_in = cleatOut; // input char array
strm.avail_out = zipOutLength; // size of output
strm.next_out = zipOut; // output char array
ret = inflate(&strm, Z_FINISH);
int deLength = zipOutLength - strm.avail_out;
cipherMetaDataFile.write((char*)zipOut, deLength);
readSize += temp;
}
}
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, metaTag);
EVP_DecryptFinal_ex(ctx, cleatOut, (int*)&outLength);
if (outLength > 0) {
strm.avail_in = outLength; // size of input, string + terminator
strm.next_in = cleatOut; // input char array
strm.avail_out = zipOutLength; // size of output
strm.next_out = zipOut; // output char array
ret = inflate(&strm, Z_FINISH);
int deLength = zipOutLength - strm.avail_out;
cipherMetaDataFile.write((char*)zipOut, deLength);
}
inflateEnd(&strm);
cipherMetaDataFile.flush();
sourceMeataDataFile.close();
cipherMetaDataFile.close();
EVP_CIPHER_CTX_free(ctx);
if (preIV)delete[] preIV;
if (preCTAndTag)delete[] preCTAndTag;
if (preCT)delete[] preCT;
if (preTag)delete[] preTag;
if (passphrase)delete[] passphrase;
if (sessionKey)delete[] sessionKey;
if (refIV)delete[] refIV;
if (zipOut)delete[] zipOut;
if (cleatOut)delete[] cleatOut;
strfilepath = encryptfile;
isenc = true;
}
else {
strfilepath = path + "\\" + filename;
}
FILE* file;
struct stat st;
if (!fopen_s(&file, strfilepath.c_str(), "rb") == 0) {
return false;
}
// double fixDis = 1000 * 10;
// if (m_ArmCfg->m_acc != 0)
// {
// fixDis = abs((m_CoverCfg->m_cover_shift_speed*m_CoverCfg->m_cover_shift_speed - m_CoverCfg->m_cover_speed*m_CoverCfg->m_cover_speed) / 2.0 / m_ArmCfg->m_acc);
// }
// if (fixDis < 1000 * 10)fixDis = 1000 * 10;
// parseAssist.fixDis = fixDis;
XML_SetUserData(m_Parser, this);
ClearBFileMap();
ClearBlockMap();
ClearRemoteBlockMap();
ClearPrevBlockMap();
m_currentLayer = NULL;
/*if (bfileinfos.size()>250) {
for (size_t i = 0; i < bfileinfos.size(); ++i) {
ifstream* ifs = new ifstream();
//ifs->open(bfileinfos[i].file_path, ios::binary | ios::in);
//bool rel = ifs->is_open();
m_binary_file_map[bfileinfos[i].file_name] = ifs;
ifstream* pre_ifs = new ifstream();
// pre_ifs->open(bfileinfos[i].file_path, ios::binary | ios::in);
//rel = pre_ifs->is_open();
m_pre_file_map[bfileinfos[i].file_name] = pre_ifs;
}
m_DyFileStream = true;
}
else {*/
for (size_t i = 0; i < bfileinfos.size(); ++i) {
ifstream* ifs = new ifstream();
ifs->open(bfileinfos[i].file_path, ios::binary | ios::in);
bool rel = ifs->is_open();
m_binary_file_map[bfileinfos[i].file_name] = ifs;
ifstream* pre_ifs = new ifstream();
pre_ifs->open(bfileinfos[i].file_path, ios::binary | ios::in);
rel = pre_ifs->is_open();
m_pre_file_map[bfileinfos[i].file_name] = pre_ifs;
}
fstat(_fileno(file), &st);
m_TotalBytes = st.st_size;
size_t readsize = 1024 * 1024 * 10;
size_t remainSize = 1024;
char* readBuffer = new char[readsize];
char* parseBuffer = new char[readsize + remainSize];
char* preRemains = new char[remainSize];
int preRemainSize = 0;
while (!feof(file)) {
memset(readBuffer, '\0', readsize);
memset(parseBuffer, '\0', readsize + remainSize);
size_t rsize = fread(readBuffer, 1, readsize, file);
if (rsize < readsize) {
if (preRemainSize > 0) {
memcpy(parseBuffer, preRemains, preRemainSize);
}
memcpy(parseBuffer + preRemainSize, readBuffer, rsize);
XML_Parse(m_Parser, parseBuffer, rsize + preRemainSize, true);
}
else {
char* pos = strrchr(readBuffer, '>');
uint64_t remainTempSize = 0;
if (pos) {
if (preRemainSize > 0) {
memcpy(parseBuffer, preRemains, preRemainSize);
}
memcpy(parseBuffer + preRemainSize, readBuffer, pos - readBuffer + 1);
remainTempSize = readBuffer + rsize - 1 - pos;
memset(preRemains, '\0', remainSize);
if (remainTempSize > 0) {
memcpy(preRemains, pos + 1, remainTempSize);
}
}
XML_Parse(m_Parser, parseBuffer, rsize + preRemainSize - remainTempSize, false);
preRemainSize = remainTempSize;;
}
}
fclose(file);
m_ReadBytes = st.st_size;
JobController::SetLoadProgress(1.0f);
delete[] readBuffer;
readBuffer = NULL;
delete[] parseBuffer;
parseBuffer = NULL;
delete[] preRemains;
preRemains = NULL;
XML_ParserFree(m_Parser);
if (isenc) {
DeleteFileA(strfilepath.c_str());
}
if (m_ExtCfg->m_CheckDataWhenInport) {
JobController::m_LoadProgressInfoFlag = JobController::CkeckingJobData;
//m_ProgressInfo = _(u8"正在检验数据").c_str();
//m_ProgressValue = 0;
JobController::SetLoadProgress(0.0f);
unsigned int layercount = layers->vector_layers.size();
for (size_t layerIndex = 0; layerIndex < layers->vector_layers.size(); ++layerIndex) {
if (!LoadLayerByIndex(layerIndex)) {
char ebuffer[200];
sprintf_s(ebuffer, sizeof(ebuffer), _(u8"检测到第%d层数据有错误").c_str(), layerIndex + 1);
m_Errors.push_back(ebuffer);
break;
}
JobController::SetLoadProgress((float)(layerIndex + 1) / layercount);
}
}
return true;
}
bool JobMetaData::LoadLayerByIndex(unsigned int lindex)
{
bool rel = true;
if (lindex >= layers->vector_layers.size())return false;
LockMainDB();
Layer* layer = layers->vector_layers[lindex];
ClearBlockMap();
vector<DataBlock*> datablocks = layer->data_blocks;
for (size_t i = 0; i < datablocks.size(); ++i) {
BinaryFile* pbf = binary_files[datablocks[i]->bin->file_id];
if (!pbf)break;
ifstream* ifs = m_binary_file_map[pbf->name];
if (!ifs)break;
BPBinary::BinDataBlock* pbindb = new BPBinary::BinDataBlock;
ifs->seekg(datablocks[i]->bin->pos, ios::beg);
if (!ReadBDataBlock(layer->layer_summary, datablocks[i]->belongPart->layerDimensions,pbindb, ifs)) {
delete pbindb;
rel = false;
break;
}
m_block_map[datablocks[i]] = pbindb;
}
m_currentLayer = layer;
UnLockMainDB();
return rel;
}
bool JobMetaData::LoadLayer(Layer* layer)
{
bool rel = true;
if (layer == NULL) return false;
LockMainDB();
ClearBlockMap();
vector<DataBlock*> datablocks = layer->data_blocks;
for (size_t i = 0; i < datablocks.size(); ++i) {
BinaryFile* pbf = binary_files[datablocks[i]->bin->file_id];
if (!pbf)break;
ifstream* ifs = m_binary_file_map[pbf->name];
if (!ifs)break;
BPBinary::BinDataBlock* pbindb = new BPBinary::BinDataBlock;
ifs->seekg(datablocks[i]->bin->pos, ios::beg);
if (!ReadBDataBlock(layer->layer_summary, datablocks[i]->belongPart->layerDimensions, pbindb, ifs)) {
delete pbindb;
rel = false;
break;
}
m_block_map[datablocks[i]] = pbindb;
}
m_currentLayer = layer;
UnLockMainDB();
return rel;
}
void JobMetaData::SetJobContent(JobContent* job_content)
{
m_job_content = job_content;
}
bool JobMetaData::LoadPrevLayer(Layer* layer)
{
if (layer == NULL) return false;
ClearPrevBlockMap();
vector<DataBlock*> datablocks = layer->data_blocks;
for (size_t i = 0; i < datablocks.size(); ++i) {
BinaryFile* pbf = binary_files[datablocks[i]->bin->file_id];
if (!pbf)break;
ifstream* ifs = m_pre_file_map[pbf->name];
if (!ifs)break;
BPBinary::BinDataBlock* pbindb = new BPBinary::BinDataBlock;
ifs->seekg(datablocks[i]->bin->pos, ios::beg);
ReadBDataBlock(layer->layer_summary, datablocks[i]->belongPart->layerDimensions, pbindb, ifs);
m_prev_block_map[datablocks[i]] = pbindb;
}
m_previewLayer = layer;
return true;
}
bool JobMetaData::LoadPrevLayerByIndex(unsigned int lindex)
{
if (lindex >= layers->vector_layers.size())return false;
Layer* layer = layers->vector_layers[lindex];
ClearPrevBlockMap();
vector<DataBlock*> datablocks = layer->data_blocks;
for (size_t i = 0; i < datablocks.size(); ++i) {
BinaryFile* pbf = binary_files[datablocks[i]->bin->file_id];
if (!pbf)break;
ifstream* ifs = m_pre_file_map[pbf->name];
if (!ifs)break;
BPBinary::BinDataBlock* pbindb = new BPBinary::BinDataBlock;
ifs->seekg(datablocks[i]->bin->pos, ios::beg);
ReadBDataBlock(layer->layer_summary, datablocks[i]->belongPart->layerDimensions, pbindb, ifs);
m_prev_block_map[datablocks[i]] = pbindb;
}
m_previewLayer = layer;
return true;
}
bool JobMetaData::LoadRemoteLayerByIndex(unsigned int lindex)
{
if (lindex >= layers->vector_layers.size())return false;
Layer* layer = layers->vector_layers[lindex];
ClearRemoteBlockMap();
vector<DataBlock*> datablocks = layer->data_blocks;
for (size_t i = 0; i < datablocks.size(); ++i) {
BinaryFile* pbf = binary_files[datablocks[i]->bin->file_id];
if (!pbf)break;
ifstream* ifs = m_pre_file_map[pbf->name];
if (!ifs)break;
BPBinary::BinDataBlock* pbindb = new BPBinary::BinDataBlock;
ifs->seekg(datablocks[i]->bin->pos, ios::beg);
ReadBDataBlock(layer->layer_summary, datablocks[i]->belongPart->layerDimensions, pbindb, ifs);
m_remote_block_map[datablocks[i]] = pbindb;
}
m_RemoteLayer = layer;
return true;
}
bool JobMetaData::LoadFirstLayer()
{
bool rel = true;
if (layers->vector_layers.empty())return false;
Layer* layer = layers->vector_layers[0];
for (map<DataBlock*, BPBinary::BinDataBlock*>::iterator it = m_FirstLayerBlockMap.begin(); it != m_FirstLayerBlockMap.end(); ++it) {
delete it->second;
}
m_FirstLayerBlockMap.clear();
vector<DataBlock*> datablocks = layer->data_blocks;
for (size_t i = 0; i < datablocks.size(); ++i) {
BinaryFile* pbf = binary_files[datablocks[i]->bin->file_id];
if (!pbf)break;
ifstream* ifs = m_binary_file_map[pbf->name];
if (!ifs)break;
BPBinary::BinDataBlock* pbindb = new BPBinary::BinDataBlock;
ifs->seekg(datablocks[i]->bin->pos, ios::beg);
if (!ReadBDataBlock(layer->layer_summary, datablocks[i]->belongPart->layerDimensions, pbindb, ifs)) {
delete pbindb;
rel = false;
break;
}
m_FirstLayerBlockMap[datablocks[i]] = pbindb;
}
return rel;
}
bool JobMetaData::ReadBDataBlock(LayerSummary* summary, Dimensions* partLayerDimensions, BPBinary::BinDataBlock* datablock, ifstream* ifs)
{
float xmax = summary->xmax + 5.0f;
float xmin = summary->xmin - 5.0f;
float ymax = summary->ymax + 5.0f;
float ymin = summary->ymin - 5.0f;
bool rel = true;
BPBinary::BHeader header;
ifs->read((char*)&header, sizeof(BPBinary::BHeader));
ifs->read((char*)&header, sizeof(BPBinary::BHeader));
unsigned char datablocktype = 0;
ifs->read((char*)&datablocktype, sizeof(datablocktype));
datablock->type = datablocktype;
char buffer[36];
ifs->read(buffer, sizeof(buffer));
ifs->read((char*)&header, sizeof(BPBinary::BHeader));
if (datablocktype == BIN_VECTOR) {
unsigned int count = header.datasize / 16;
for (unsigned int i = 0; i < count; ++i) {
BPBinary::VectorPoint* point = new BPBinary::VectorPoint;
ifs->read((char*)point, sizeof(BPBinary::VectorPoint));
if (point->x1 < partLayerDimensions->xmin)partLayerDimensions->xmin = point->x1;
if (point->x2 < partLayerDimensions->xmin)partLayerDimensions->xmin = point->x2;
if (point->x1 > partLayerDimensions->xmax)partLayerDimensions->xmax = point->x1;
if (point->x2 > partLayerDimensions->xmax)partLayerDimensions->xmax = point->x2;
if (point->y1 < partLayerDimensions->ymin)partLayerDimensions->ymin = point->y1;
if (point->y2 < partLayerDimensions->ymin)partLayerDimensions->ymin = point->y2;
if (point->y1 > partLayerDimensions->ymax)partLayerDimensions->ymax = point->y1;
if (point->y2 > partLayerDimensions->ymax)partLayerDimensions->ymax = point->y2;
if (m_ExtCfg->m_CheckDataWhenInport) {
if (((point->x1 > xmax) || (point->x1 < xmin)) ||
((point->x2 > xmax) || (point->x2 < xmin)) ||
((point->y1 > ymax) || (point->y1 < ymin)) ||
((point->y2 > ymax) || (point->y2 < ymin))) {
rel = false;
delete point;
break;
}
}
datablock->point_indexs.push_back(point);
}
}
else if (datablocktype == BIN_CHAIN) {
unsigned int hadReadSize = 0;
unsigned int datalenth = 0;
do {
unsigned int remainSize = header.datasize - hadReadSize;
ifs->read((char*)&datalenth, sizeof(datalenth));
hadReadSize += 4;
if (datalenth * 8 > remainSize) {
rel = false;
break;
}
else {
if (datalenth > 0) {
BPBinary::ChainPoint* pcp = new BPBinary::ChainPoint;
pcp->num_of_point = datalenth;
bool hasError = false;
for (unsigned int i = 0; i < pcp->num_of_point; ++i) {
BPBinary::BPoint* pb = new BPBinary::BPoint;
ifs->read((char*)pb, sizeof(BPBinary::BPoint));
if (pb->x < partLayerDimensions->xmin)partLayerDimensions->xmin = pb->x;
if (pb->x > partLayerDimensions->xmax)partLayerDimensions->xmax = pb->x;
if (pb->y < partLayerDimensions->ymin)partLayerDimensions->ymin = pb->y;
if (pb->y > partLayerDimensions->ymax)partLayerDimensions->ymax = pb->y;
if (m_ExtCfg->m_CheckDataWhenInport) {
if (((pb->x > xmax) || (pb->x < xmin)) ||
((pb->y > ymax) || (pb->y < ymin))) {
rel = false;
hasError = true;
delete pb;
break;
}
}
pcp->points.push_back(pb);
}
if (hasError) {
delete pcp;
rel = false;
break;
}
datablock->point_indexs.push_back(pcp);
hadReadSize += (datalenth * 8);
}
}
} while (datalenth != 0);
}
return rel;
}
/*
bool JobMetaData::ReadBChains(LayerSummary* summary,BPBinary::ChainPoint* chainpoint, ifstream* ifs)
{
bool rel = true;
float xmax = summary->xmax + 0.1f;
float xmin = summary->xmin - 0.1f;
float ymax = summary->ymax + 0.1f;
float ymin = summary->ymin - 0.1f;
for (unsigned int i = 0; i < chainpoint->num_of_point; ++i) {
BPBinary::BPoint* pb = new BPBinary::BPoint;
ifs->read((char*)pb, sizeof(BPBinary::BPoint));
if (((pb->x > xmax) || (pb->x < xmin)) ||
((pb->y > ymax) || (pb->y < ymin))) {
rel = false;
delete pb;
break;
}
chainpoint->points.push_back(pb);
}
return rel;
}
*/
void XMLCALL JobMetaData::StartElement(void *userData, const XML_Char *name, const XML_Char **attrs)
{
JobMetaData* job = (JobMetaData*)userData;
string strname(name);
if (strcmp(name, "References") == 0) {
for (int i = 0; attrs[i] != 0; i += 2)
{
if (strcmp(attrs[i], "Part") == 0 && attrs[i + 1] != 0) {
job->parseAssist.lastDataBlock->references->part = stoi(string(attrs[i + 1]));
}
else if (strcmp(attrs[i], "Process") == 0 && attrs[i + 1] != 0) {
job->parseAssist.lastDataBlock->references->process = stoi(string(attrs[i + 1]));
}
}
vector<DataBlock*>* blocks = job->parseAssist.lastLayer->data_blocks_map[job->parseAssist.lastDataBlock->references->part];
if (blocks == NULL)
{
blocks = new vector<DataBlock*>();
blocks->push_back(job->parseAssist.lastDataBlock);
job->parseAssist.lastLayer->data_blocks_map[job->parseAssist.lastDataBlock->references->part] = blocks;
}
else {
blocks->push_back(job->parseAssist.lastDataBlock);
}
ParameterSet* ps= job->parameterMap[job->parseAssist.lastDataBlock->references->process];
Part* part = job->partsMap[job->parseAssist.lastDataBlock->references->part];
part->paramSet.insert(ps);
}
else if (strcmp(name, "Summary") == 0) {
for (int i = 0; attrs[i] != 0; i += 2)
{
if (strcmp(attrs[i], "MarkDistance") == 0 && attrs[i + 1] != 0) {
job->parseAssist.lastDataBlock->data_block_summary->mark_distance = stof(string(attrs[i + 1]));
}
else if (strcmp(attrs[i], "JumpDistance") == 0 && attrs[i + 1] != 0) {
job->parseAssist.lastDataBlock->data_block_summary->jump_distance = stof(string(attrs[i + 1]));
}
else if (strcmp(attrs[i], "NumMarkSegments") == 0 && attrs[i + 1] != 0) {
job->parseAssist.lastDataBlock->data_block_summary->num_mark_segments = stoi(string(attrs[i + 1]));
}
else if (strcmp(attrs[i], "NumJumpSegments") == 0 && attrs[i + 1] != 0) {
job->parseAssist.lastDataBlock->data_block_summary->num_jump_segments = stoi(string(attrs[i + 1]));
}
}
}
else if (strcmp(name, "Bin") == 0) {
for (int i = 0; attrs[i] != 0; i += 2)
{
if (strcmp(attrs[i], "FileID") == 0 && attrs[i + 1] != 0) {
job->parseAssist.lastDataBlock->bin->file_id = stoi(string(attrs[i + 1]));
}
else if (strcmp(attrs[i], "Pos") == 0 && attrs[i + 1] != 0) {
job->parseAssist.lastDataBlock->bin->pos = stoull(string(attrs[i + 1]));
}
}
}
else if (strcmp(name, "DataBlock") == 0) {
DataBlock* dataBlock = new DataBlock();
job->parseAssist.lastDataBlock = dataBlock;
job->parseAssist.lastLayer->data_blocks.push_back(dataBlock);
}
else if (strcmp(name, "Layer") == 0) {
Layer* layer = new Layer();
layer->index = job->layers->vector_layers.size();
//layer->layer_thickness = job->layers->layer_thickness;
//layer->powder = layer->layer_thickness * 2;
job->parseAssist.lastLayer = layer;
job->layers->vector_layers.push_back(layer);
}
else if (strcmp(name, "BinaryFile") == 0) {
BinaryFile* bf = new BinaryFile();
job->parseAssist.lastBinaryFile = bf;
}
else if (strcmp(name, "Type") == 0) {
job->parseAssist.tempValue = "Other";
}
else if (strcmp(name, "ParameterSet") == 0) {
ParameterSet* ps = new ParameterSet();
job->parseAssist.lastParameterSet = ps;
for (int i = 0; attrs[i] != 0; i += 2)
{
if (strcmp(attrs[i], "ScanField") == 0 && attrs[i + 1] != 0) {
ps->scan_field = stoi(string(attrs[i + 1]));
}
}
}
else if (strcmp(name, "Part") == 0) {
Part* part = new Part();
job->parseAssist.lastPart = part;
job->partsVec.push_back(part);
}
else if (strcmp(name, "Dimension") == 0) {
for (int i = 0; attrs[i] != 0; i += 2)
{
if (strcmp(attrs[i], "XMin") == 0 && attrs[i + 1] != 0) {
job->parseAssist.lastScanField->dimension->xmin = stof(string(attrs[i + 1]));
}
else if (strcmp(attrs[i], "YMin") == 0 && attrs[i + 1] != 0) {
job->parseAssist.lastScanField->dimension->ymin = stof(string(attrs[i + 1]));
}
else if (strcmp(attrs[i], "XMax") == 0 && attrs[i + 1] != 0) {
job->parseAssist.lastScanField->dimension->xmax = stof(string(attrs[i + 1]));
}
else if (strcmp(attrs[i], "YMax") == 0 && attrs[i + 1] != 0) {
job->parseAssist.lastScanField->dimension->ymax = stof(string(attrs[i + 1]));
}
}
}
else if (strcmp(name, "ScanField") == 0) {
ScanField* sf = new ScanField();
for (int i = 0; attrs[i] != 0; i += 2)
{
if (strcmp(attrs[i], "ID") == 0 && attrs[i + 1] != 0) {
sf->id = stoi(string(attrs[i + 1]));
}
else if (strcmp(attrs[i], "Reference") == 0 && attrs[i + 1] != 0) {
sf->reference = stoi(string(attrs[i + 1]));
}
}
job->machine_type->scanFields.push_back(sf);
job->parseAssist.lastScanField = sf;
}
else if (strcmp(name, "Laser") == 0) {
Laser* laser = new Laser();
for (int i = 0; attrs[i] != 0; i += 2)
{
if (strcmp(attrs[i], "ID") == 0 && attrs[i + 1] != 0) {
laser->id = stoi(string(attrs[i + 1]));
}
else if (strcmp(attrs[i], "Reference") == 0 && attrs[i + 1] != 0) {
laser->reference = stoi(string(attrs[i + 1]));
}
}
job->machine_type->lasers.push_back(laser);
}
else if (strcmp(name, "Property") == 0) {
string str = job->parseAssist.depthMap[job->parseAssist.depth - 2];
if (str == "GeneralInfo")
{
Property* property = new Property();
for (int i = 0; attrs[i] != 0; i += 2)
{
if (strcmp(attrs[i], "Name") == 0 && attrs[i + 1] != 0) {
property->name = attrs[i + 1];
}
else if (strcmp(attrs[i], "Type") == 0 && attrs[i + 1] != 0) {
property->type = attrs[i + 1];
}
}
job->general_info->properties.push_back(property);
job->parseAssist.tempProperty = property;
}
}
else if (strcmp(name, "Application") == 0) {
//job->file_info->written_by->application = new JobMetaData::Application;
for (int i = 0; attrs[i] != 0; i += 2)
{
if (strcmp(attrs[i], "Name") == 0) {
job->file_info->written_by->application->name = string(attrs[i + 1]);
}
else if (strcmp(attrs[i], "Version") == 0) {
job->file_info->written_by->application->version = string(attrs[i + 1]);
}
}
}
job->parseAssist.depth++;
job->parseAssist.depthMap[job->parseAssist.depth] = strname;
int bytes = XML_GetCurrentByteCount(job->m_Parser);
job->m_ReadBytes += bytes;
if (job->m_TotalBytes > 0) {
JobController::SetLoadProgress((float)job->m_ReadBytes / job->m_TotalBytes);
}
}
void XMLCALL JobMetaData::EndElement(void *userData, const XML_Char *name)
{
JobMetaData* job = (JobMetaData*)userData;
if (strcmp(name, "DataBlock") == 0) {
ParameterSet* ps = job->parameterMap[job->parseAssist.lastDataBlock->references->process];
if (ps) {
ScannerControlCfg* laserCfg = NULL;
MetaData::Part* part = job->GetPart(job->parseAssist.lastDataBlock->references->part);
job->parseAssist.lastDataBlock->belongPart = part;
job->parseAssist.lastLayer->parts[part->id] = part;
if (job->m_MachineCfg->IsDataStrategy()) {
laserCfg = job->m_FieldRefScanLaser[ps->scan_field];
}
if (laserCfg) {
job->m_DBRefScanLaser[job->parseAssist.lastDataBlock] = laserCfg->m_SeqNo;
}
}
}
if (strcmp(name, "TotalMarkDistance") == 0) {
job->parseAssist.lastLayer->layer_summary->total_mark_distance = stof(job->parseAssist.tempValue);
}
else if (strcmp(name, "TotalJumpDistance") == 0) {
job->parseAssist.lastLayer->layer_summary->total_jump_distance = stof(job->parseAssist.tempValue);
}
else if (strcmp(name, "XMin") == 0) {
job->parseAssist.lastLayer->layer_summary->xmin = stof(job->parseAssist.tempValue);
}
else if (strcmp(name, "XMax") == 0) {
job->parseAssist.lastLayer->layer_summary->xmax = stof(job->parseAssist.tempValue);
}
else if (strcmp(name, "YMin") == 0) {
job->parseAssist.lastLayer->layer_summary->ymin = stof(job->parseAssist.tempValue);
}
else if (strcmp(name, "YMax") == 0) {
job->parseAssist.lastLayer->layer_summary->ymax = stof(job->parseAssist.tempValue);
}
else if (strcmp(name, "LayerScanTime") == 0) {
job->parseAssist.lastLayer->layer_scan_time = stof(job->parseAssist.tempValue);
}
else if (strcmp(name, "Z") == 0) {
float layerZ = stof(job->parseAssist.tempValue);
job->parseAssist.lastLayer->z = layerZ*1000.0f + 0.5f;
}
else if (strcmp(name, "LayerRecoatingTime") == 0) {
job->layers->layer_recoating_time = stof(job->parseAssist.tempValue);
}
else if (strcmp(name, "LayerThickness") == 0) {
float layerThick = stof(job->parseAssist.tempValue);
job->layers->layer_thickness = layerThick*1000.0f + 0.5f;
}
else if (strcmp(name, "Layer") == 0) {
}
else if (strcmp(name, "FileSize") == 0) {
job->parseAssist.lastBinaryFile->filesize = stoull(job->parseAssist.tempValue);
}
else if (strcmp(name, "Name") == 0) {
string str = job->parseAssist.depthMap[job->parseAssist.depth - 1];
if (str == "Part") {
if (job->parseAssist.lastPart)
{
Part* part = job->parseAssist.lastPart;
part->name = job->parseAssist.tempValue;
}
}
else if (str == "ParameterSet") {
if (job->parseAssist.lastParameterSet)
{
job->parseAssist.lastParameterSet->name = job->parseAssist.tempValue;
}
}
else if (str == "BinaryFile") {
if (job->parseAssist.lastBinaryFile) {
job->parseAssist.lastBinaryFile->name = job->parseAssist.tempValue;
}
}
}
else if (strcmp(name, "ID") == 0) {
string str = job->parseAssist.depthMap[job->parseAssist.depth - 1];
if (str == "Part") {
if (job->parseAssist.lastPart)
{
Part* part = job->parseAssist.lastPart;
part->id = stoi(job->parseAssist.tempValue);
job->partsMap[part->id] = part;
//job->partRefParameterMap[part->id] = new vector<int>();
}
}
else if (str == "ParameterSet") {
if (job->parseAssist.lastParameterSet)
{
job->parseAssist.lastParameterSet->id = stoi(job->parseAssist.tempValue);
job->parameterMap[job->parseAssist.lastParameterSet->id] = job->parseAssist.lastParameterSet;
}
}
else if (str == "LaserSet") {
if (job->parseAssist.lastParameterSet)
{
job->parseAssist.lastParameterSet->laser_set->id = stoi(job->parseAssist.tempValue);
}
}
else if (str == "BinaryFile") {
if (job->parseAssist.lastBinaryFile) {
job->parseAssist.lastBinaryFile->id = stoi(job->parseAssist.tempValue);
job->binary_files[job->parseAssist.lastBinaryFile->id] = job->parseAssist.lastBinaryFile;
}
}
}
else if (strcmp(name, "LaserDiameter") == 0) {
if (job->parseAssist.lastParameterSet)
{
job->parseAssist.lastParameterSet->laser_set->laser_diameter = stof(job->parseAssist.tempValue);
}
}
else if (strcmp(name, "LaserPower") == 0) {
if (job->parseAssist.lastParameterSet)
{
job->parseAssist.lastParameterSet->laser_set->laser_power = stof(job->parseAssist.tempValue);
}
}
else if (strcmp(name, "Type") == 0) {
if (job->parseAssist.lastParameterSet)
{
job->parseAssist.lastParameterSet->set_type = job->parseAssist.tempValue;
}
}
else if (strcmp(name, "LaserSpeed") == 0) {
if (job->parseAssist.lastParameterSet)
{
job->parseAssist.lastParameterSet->laser_speed = stof(job->parseAssist.tempValue);
}
}
else if (strcmp(name, "Xmin") == 0) {
string str = job->parseAssist.depthMap[job->parseAssist.depth - 1];
if (str == "JobDimensions") {
sscanf_s(job->parseAssist.tempValue.c_str(), "%f", &job->general_info->job_dimensions->xmin);
}
else if (str == "Dimensions") {
if (job->parseAssist.lastPart) {
job->parseAssist.lastPart->dimensions->xmin = stof(job->parseAssist.tempValue);
}
}
}
else if (strcmp(name, "Ymin") == 0) {
string str = job->parseAssist.depthMap[job->parseAssist.depth - 1];
if (str == "JobDimensions") {
job->general_info->job_dimensions->ymin = stof(job->parseAssist.tempValue);
}
else if (str == "Dimensions") {
if (job->parseAssist.lastPart) {
job->parseAssist.lastPart->dimensions->ymin = stof(job->parseAssist.tempValue);
}
}
}
else if (strcmp(name, "Zmin") == 0) {
string str = job->parseAssist.depthMap[job->parseAssist.depth - 1];
if (str == "JobDimensions") {
job->general_info->job_dimensions->zmin = stof(job->parseAssist.tempValue);
}
else if (str == "Dimensions") {
if (job->parseAssist.lastPart) {
job->parseAssist.lastPart->dimensions->zmin = stof(job->parseAssist.tempValue);
}
}
}
else if (strcmp(name, "Xmax") == 0) {
string str = job->parseAssist.depthMap[job->parseAssist.depth - 1];
if (str == "JobDimensions") {
job->general_info->job_dimensions->xmax = stof(job->parseAssist.tempValue);
}
else if (str == "Dimensions") {
if (job->parseAssist.lastPart) {
job->parseAssist.lastPart->dimensions->xmax = stof(job->parseAssist.tempValue);
}
}
}
else if (strcmp(name, "Ymax") == 0) {
string str = job->parseAssist.depthMap[job->parseAssist.depth - 1];
if (str == "JobDimensions") {
job->general_info->job_dimensions->ymax = stof(job->parseAssist.tempValue);
}
else if (str == "Dimensions") {
if (job->parseAssist.lastPart) {
job->parseAssist.lastPart->dimensions->ymax = stof(job->parseAssist.tempValue);
}
}
}
else if (strcmp(name, "Zmax") == 0) {
string str = job->parseAssist.depthMap[job->parseAssist.depth - 1];
if (str == "JobDimensions") {
job->general_info->job_dimensions->zmax = stof(job->parseAssist.tempValue);
}
else if (str == "Dimensions") {
if (job->parseAssist.lastPart) {
job->parseAssist.lastPart->dimensions->zmax = stof(job->parseAssist.tempValue);
}
}
}
else if (strcmp(name, "Value") == 0) {
string str = job->parseAssist.depthMap[job->parseAssist.depth - 1];
if (str == "Property") {
if (job->parseAssist.tempProperty) {
job->parseAssist.tempProperty->value = job->parseAssist.tempValue;
}
}
}
else if (strcmp(name, "MachineType") == 0) {
vector<ScannerControlCfg*>* cfgs = ConfigManager::GetInstance()->GetMatchScannerControlCfg();
if (job->machine_type->scanFields.empty()) {
ScanField* sf = new ScanField();
sf->id = 0;
sf->reference = 0;
if (!cfgs->empty()) {
sf->dimension->xmin = (*cfgs)[0]->m_ScanCfgWrapper.m_CorrectParamCfg.m_xmeasure_min;
sf->dimension->xmax = (*cfgs)[0]->m_ScanCfgWrapper.m_CorrectParamCfg.m_xmeasure_max;
sf->dimension->ymin = (*cfgs)[0]->m_ScanCfgWrapper.m_CorrectParamCfg.m_ymeasure_min;
sf->dimension->ymax = (*cfgs)[0]->m_ScanCfgWrapper.m_CorrectParamCfg.m_ymeasure_max;
}
else {
sf->dimension->xmin = job->general_info->job_dimensions->xmin;
sf->dimension->xmax = job->general_info->job_dimensions->xmax;
sf->dimension->ymin = job->general_info->job_dimensions->ymin;
sf->dimension->ymax = job->general_info->job_dimensions->ymax;
}
job->machine_type->scanFields.push_back(sf);
}
if (job->m_MachineCfg->IsDataStrategy()) {
map<int, unsigned int> hasSelected;
int canSelectIndex = 0;
//检测可匹配的ScanField
for (size_t i = 0; i < job->machine_type->scanFields.size(); ++i)
{
ScanField* sf = job->machine_type->scanFields[i];
float sf_maxx = sf->dimension->xmax - sf->dimension->xmin;
float sf_maxy = sf->dimension->ymax - sf->dimension->ymin;
bool hasfind = false;
queue<int> canSelectIndexs;
for (size_t laserIndex = 0; laserIndex < cfgs->size(); ++laserIndex) {
ScannerControlCfg* cfg = (*cfgs)[laserIndex];
if (!cfg->m_IsEnable)continue;
float cfg_xmin = (float)cfg->m_ScanCfgWrapper.m_CorrectParamCfg.m_xmeasure_min;
float cfg_xmax = (float)cfg->m_ScanCfgWrapper.m_CorrectParamCfg.m_xmeasure_max;
float cfg_ymin = (float)cfg->m_ScanCfgWrapper.m_CorrectParamCfg.m_ymeasure_min;
float cfg_ymax = (float)cfg->m_ScanCfgWrapper.m_CorrectParamCfg.m_ymeasure_max;
if ((sf->dimension->xmin >= cfg_xmin) && (sf->dimension->xmax <= cfg_xmax) && (sf->dimension->ymin >= cfg_ymin) && (sf->dimension->ymax <= cfg_ymax)) {
canSelectIndexs.push(laserIndex);
if (!hasSelected[cfg->m_SeqNo]) {
job->m_FieldRefScanLaser[sf->id] = cfg;
hasSelected[cfg->m_SeqNo] = 1;
hasfind = true;
break;
}
}
}
if (!hasfind) {
if (canSelectIndexs.empty()) {
char buffer[256];
sprintf_s(buffer, sizeof(buffer), _(u8"数据中的打印区%d超出可打印范围").c_str(),
sf->id);
//EnterCriticalSection(&job->m_MsgCs);
job->m_Errors.push_back(buffer);
//LeaveCriticalSection(&job->m_MsgCs);
}
else {
int firstfix = canSelectIndexs.front();
job->m_FieldRefScanLaser[sf->id] = (*cfgs)[firstfix];
}
}
}
//检测是否越限
if (!cfgs->empty()) {
float min_x = FLT_MAX;
float max_x = FLT_MIN;
float min_y = FLT_MAX;
float max_y = FLT_MIN;
for (size_t laserindex = 0; laserindex < cfgs->size(); ++laserindex) {
ScannerControlCfg* cfg = (*cfgs)[laserindex];
if (cfg->m_ScanCfgWrapper.m_CorrectParamCfg.m_xmeasure_min < min_x)min_x = cfg->m_ScanCfgWrapper.m_CorrectParamCfg.m_xmeasure_min;
if (cfg->m_ScanCfgWrapper.m_CorrectParamCfg.m_xmeasure_max > max_x)max_x = cfg->m_ScanCfgWrapper.m_CorrectParamCfg.m_xmeasure_max;
if (cfg->m_ScanCfgWrapper.m_CorrectParamCfg.m_ymeasure_min < min_y)min_y = cfg->m_ScanCfgWrapper.m_CorrectParamCfg.m_ymeasure_min;
if (cfg->m_ScanCfgWrapper.m_CorrectParamCfg.m_ymeasure_max > max_y)max_y = cfg->m_ScanCfgWrapper.m_CorrectParamCfg.m_ymeasure_max;
}
if ((job->general_info->job_dimensions->xmin < min_x) || (job->general_info->job_dimensions->xmax > max_x)) {
//EnterCriticalSection(&job->m_MsgCs);
job->m_Errors.push_back(_(u8"x方向数据超可打印范围").c_str());
//LeaveCriticalSection(&job->m_MsgCs);
}
if((job->general_info->job_dimensions->ymin < min_y) || (job->general_info->job_dimensions->ymax > max_y)) {
//EnterCriticalSection(&job->m_MsgCs);
job->m_Errors.push_back(_(u8"y方向数据超可打印范围").c_str());
//LeaveCriticalSection(&job->m_MsgCs);
}
}
}
}
else if (strcmp(name, "Layers") == 0) {
Layer* llayer = NULL;
float lthick = 0.0f;
for (size_t i = 0; i < job->layers->vector_layers.size(); i++) {
Layer * templ = job->layers->vector_layers[i];
if (llayer)
{
llayer->layer_thickness = templ->z - llayer->z;
llayer->powder = llayer->layer_thickness * 2;
lthick = llayer->layer_thickness;
}
llayer = templ;
}
if (llayer)
{
llayer->layer_thickness = lthick;
llayer->powder = lthick * 2;
}
job->ReCalcEvaTime();
}
/*else if (strcmp(name, "Part") == 0) {
job->parseAssist.lastPart->center_x = (job->parseAssist.lastPart->dimensions->xmax - job->parseAssist.lastPart->dimensions->xmin) / 2.0f;
job->parseAssist.lastPart->center_x = (job->parseAssist.lastPart->dimensions->xmax - job->parseAssist.lastPart->dimensions->xmin) / 2.0f;
}*/
else if (strcmp(name, "Parts") == 0) {
for (size_t partIndex = 0; partIndex < job->partsVec.size(); ++partIndex) {
Part* part = job->partsVec[partIndex];
part->partPosBean.m_JobId = job->job_id;
part->partPosBean.m_PartCenterX = (part->dimensions->xmax + part->dimensions->xmin) / 2.0f;
part->partPosBean.m_PartCenterY = (part->dimensions->ymax + part->dimensions->ymin) / 2.0f;
part->partPosBean.m_SrcPartCenterX = part->partPosBean.m_PartCenterX;
part->partPosBean.m_SrcPartCenterY = part->partPosBean.m_PartCenterY;
}
}
else if (strcmp(name, "Material") == 0) {
job->general_info->material = job->parseAssist.tempValue;
}
else if (strcmp(name, "JobName") == 0) {
job->general_info->job_name = job->parseAssist.tempValue;
}
else if (strcmp(name, "Major") == 0) {
job->file_info->version->major = stoi(job->parseAssist.tempValue);
}
else if (strcmp(name, "Minor") == 0) {
job->file_info->version->minor = stoi(job->parseAssist.tempValue);
}
else if (strcmp(name, "Revision") == 0) {
job->file_info->version->revision = stoi(job->parseAssist.tempValue);
}
else if (strcmp(name, "JobID") == 0) {
job->job_id = job->parseAssist.tempValue;
}
job->parseAssist.depth--;
int bytes = XML_GetCurrentByteCount(job->m_Parser);
job->m_ReadBytes += bytes;
if (job->m_TotalBytes > 0) {
JobController::SetLoadProgress((float)job->m_ReadBytes / job->m_TotalBytes);
}
}
void XMLCALL JobMetaData::DataHandler(void *userData, const XML_Char *s, int len)
{
JobMetaData* job = (JobMetaData*)userData;
char buffer[512];
memset(buffer, '\0', 512);
memcpy(buffer, s, len);
job->parseAssist.tempValue = string(buffer);
job->m_ReadBytes += len;
if (job->m_TotalBytes > 0) {
JobController::SetLoadProgress((float)job->m_ReadBytes / job->m_TotalBytes);
}
}
void JobMetaData::AddPart(Part* part)
{
if (!part)return;
LockPart();
partsVec.push_back(part);
partsMap[part->id] = part;
for (size_t i = 0; i < layers->vector_layers.size(); ++i) {
vector<DataBlock*>* dbs = layers->vector_layers[i]->data_blocks_map[part->sourceId];
//layers->vector_layers[i]->data_blocks_map[part->id] = layers->vector_layers[i]->data_blocks_map[part->sourceId];
for (size_t dbIndex = 0; dbIndex < dbs->size();++dbIndex) {
DataBlock* db = new DataBlock();
db->references->part = part->id;
db->references->process = (*dbs)[dbIndex]->references->process;
memcpy_s(db->data_block_summary, sizeof(DataBlockSummary), (*dbs)[dbIndex]->data_block_summary, sizeof(DataBlockSummary));
memcpy_s(db->bin, sizeof(Bin), (*dbs)[dbIndex]->bin, sizeof(Bin));
layers->vector_layers[i]->data_blocks.push_back(db);
vector<DataBlock*>* blocks = layers->vector_layers[i]->data_blocks_map[part->id];
if (blocks == NULL)
{
blocks = new vector<DataBlock*>();
blocks->push_back(db);
layers->vector_layers[i]->data_blocks_map[part->id] = blocks;
}
else {
blocks->push_back(db);
}
}
}
UnLockPart();
if (m_previewLayer) {
LoadPrevLayer(m_previewLayer);
}
}
void JobMetaData::DelPart(Part* part)
{
if (!part)return;
LockPart();
for (size_t i = 0; i < layers->vector_layers.size(); ++i) {
vector<DataBlock*> dbs = layers->vector_layers[i]->data_blocks;
for (vector<DataBlock*>::iterator it = layers->vector_layers[i]->data_blocks.begin(); it != layers->vector_layers[i]->data_blocks.end();) {
DataBlock* db = (*it);
if (db &&db->references->part == part->id) {
delete db;
it = layers->vector_layers[i]->data_blocks.erase(it);
}
else {
it++;
}
}
map<int, vector<DataBlock*>*>::iterator dbmapit;
if ((dbmapit=layers->vector_layers[i]->data_blocks_map.find(part->id)) != layers->vector_layers[i]->data_blocks_map.end()) {
vector<DataBlock*>* pdbs = layers->vector_layers[i]->data_blocks_map[part->id];
delete pdbs;
layers->vector_layers[i]->data_blocks_map.erase(dbmapit);
}
}
map<int, Part*>::iterator partit;
if ((partit = partsMap.find(part->id)) != partsMap.end()) {
partsMap.erase(partit);
}
for (vector<Part*>::iterator it = partsVec.begin(); it != partsVec.end();) {
Part* temp = (*it);
if (temp && temp == part) {
delete temp;
temp = nullptr;
it = partsVec.erase(it);
}
else {
it++;
}
}
UnLockPart();
if (m_previewLayer) {
LoadPrevLayer(m_previewLayer);
}
}