1 #include "FeaturesFile.h"
2 #include "ArchiveExtractor.h"
5 #include "../invalid_odb_error.h"
7 #include "../parse_error.h"
8 #include "SymbolName.h"
9 #include "equals_within.h"
13 namespace Odb::Lib::FileModel::Design
15 FeaturesFile::FeaturesFile()
24 FeaturesFile::~FeaturesFile()
26 m_featureRecords.clear();
27 m_attributeNames.clear();
28 m_attributeTextValues.clear();
29 m_symbolNamesByName.clear();
32 bool FeaturesFile::Parse(std::filesystem::path directory,
const std::string& alternateFilename )
34 std::ifstream featuresFile;
40 m_directory = directory;
42 loginfo(
"checking for extraction...");
44 std::vector<std::string> filenames;
45 if (alternateFilename.empty())
47 std::copy(std::begin(FEATURES_FILENAMES), std::end(FEATURES_FILENAMES), std::back_inserter(filenames));
51 filenames.push_back(alternateFilename);
54 std::filesystem::path featuresFilePath;
55 for (
const auto& featuresFilename : filenames)
57 loginfo(
"trying features file: [" + featuresFilename +
"]...");
59 featuresFilePath = Utils::ArchiveExtractor::getUncompressedFilePath(m_directory, featuresFilename);
60 if (exists(featuresFilePath) && is_regular_file(featuresFilePath))
62 loginfo(
"found features file: [" + featuresFilePath.string() +
"]");
67 m_path = featuresFilePath;
69 loginfo(
"any extraction complete, parsing data...");
71 if (!std::filesystem::exists(m_path))
73 auto message =
"features file does not exist: [" + m_path.string() +
"]";
74 throw invalid_odb_error(message.c_str());
76 else if (!std::filesystem::is_regular_file(m_path))
78 auto message =
"features is not a file: [" + m_path.string() +
"]";
79 throw invalid_odb_error(message.c_str());
82 featuresFile.open(m_path.string(), std::ios::in);
83 if (!featuresFile.is_open())
85 auto message =
"unable to open features file: [" + m_path.string() +
"]";
86 throw invalid_odb_error(message.c_str());
89 std::shared_ptr<FeatureRecord> pCurrentFeatureRecord;
90 std::shared_ptr<ContourPolygon> pCurrentContourPolygon;
92 while (std::getline(featuresFile, line))
97 Utils::str_trim(line);
100 std::stringstream lineStream(line);
103 if (line.find(COMMENT_TOKEN) == 0)
107 else if (line.find(UNITS_TOKEN) == 0)
111 if (!std::getline(lineStream, token,
'='))
113 throw_parse_error(m_path, line, token, lineNumber);
115 else if (!std::getline(lineStream, token,
'='))
117 throw_parse_error(m_path, line, token, lineNumber);
122 else if (line.find(
"U") == 0)
125 if (!std::getline(lineStream, token,
' '))
127 throw_parse_error(m_path, line, token, lineNumber);
129 else if (!std::getline(lineStream, token,
' '))
131 throw_parse_error(m_path, line, token, lineNumber);
136 else if (line.find(ID_TOKEN) == 0)
139 if (!std::getline(lineStream, token,
'='))
141 throw_parse_error(m_path, line, token, lineNumber);
143 else if (!std::getline(lineStream, token,
'='))
145 throw_parse_error(m_path, line, token, lineNumber);
147 m_id = std::stoul(token);
149 else if (line.find(NUM_FEATURES_TOKEN) == 0)
154 if (!(lineStream >> token))
156 throw_parse_error(m_path, line, token, lineNumber);
159 if (token != NUM_FEATURES_TOKEN)
161 throw_parse_error(m_path, line, token, lineNumber);
164 if (!(lineStream >> m_numFeatures))
166 throw_parse_error(m_path, line, token, lineNumber);
169 else if (line.find(ATTRIBUTE_NAME_TOKEN) == 0)
174 if (!std::getline(lineStream, token,
' '))
176 throw_parse_error(m_path, line, token, lineNumber);
178 else if (!std::getline(lineStream, token,
' '))
180 throw_parse_error(m_path, line, token, lineNumber);
182 m_attributeNames.push_back(token);
184 else if (line.find(ATTRIBUTE_VALUE_TOKEN) == 0)
188 if (!std::getline(lineStream, token,
' '))
190 throw_parse_error(m_path, line, token, lineNumber);
192 else if (!std::getline(lineStream, token,
' '))
194 throw_parse_error(m_path, line, token, lineNumber);
196 m_attributeTextValues.push_back(token);
198 else if (line.find(SYMBOL_NAME_TOKEN) == 0)
201 auto pSymbolName = std::make_shared<SymbolName>();
202 if (!pSymbolName->SymbolName::Parse(m_path, line, lineNumber))
204 throw_parse_error(m_path, line,
"", lineNumber);
206 m_symbolNamesByName[pSymbolName->GetName()] = pSymbolName;
208 else if (line.find(FeatureRecord::LINE_TOKEN) == 0)
211 if (!(lineStream >> token) || token != FeatureRecord::LINE_TOKEN)
213 throw_parse_error(m_path, line, token, lineNumber);
216 auto pFeatureRecord = std::make_shared<FeatureRecord>();
217 pFeatureRecord->type = FeatureRecord::Type::Line;
219 if (!(lineStream >> pFeatureRecord->xs))
221 throw_parse_error(m_path, line, token, lineNumber);
224 if (!(lineStream >> pFeatureRecord->ys))
226 throw_parse_error(m_path, line, token, lineNumber);
229 if (!(lineStream >> pFeatureRecord->xe))
231 throw_parse_error(m_path, line, token, lineNumber);
234 if (!(lineStream >> pFeatureRecord->ye))
236 throw_parse_error(m_path, line, token, lineNumber);
239 if (!(lineStream >> pFeatureRecord->sym_num))
241 throw_parse_error(m_path, line, token, lineNumber);
245 if (!(lineStream >> polarity))
247 throw_parse_error(m_path, line, token, lineNumber);
251 case 'P': pFeatureRecord->polarity = Polarity::Positive;
break;
252 case 'N': pFeatureRecord->polarity = Polarity::Negative;
break;
253 default: throw_parse_error(m_path, line, token, lineNumber);
256 if (!(lineStream >> pFeatureRecord->dcode))
258 throw_parse_error(m_path, line, token, lineNumber);
261 std::string attrIdString;
262 lineStream >> attrIdString;
264 if (!pFeatureRecord->ParseAttributeLookupTable(attrIdString))
266 throw_parse_error(m_path, line, token, lineNumber);
269 m_featureRecords.push_back(pFeatureRecord);
271 else if (line.find(FeatureRecord::PAD_TOKEN) == 0)
274 if (!(lineStream >> token) || token != FeatureRecord::PAD_TOKEN)
276 throw_parse_error(m_path, line, token, lineNumber);
279 auto pFeatureRecord = std::make_shared<FeatureRecord>();
280 pFeatureRecord->type = FeatureRecord::Type::Pad;
282 if (!(lineStream >> pFeatureRecord->x))
284 throw_parse_error(m_path, line, token, lineNumber);
287 if (!(lineStream >> pFeatureRecord->y))
289 throw_parse_error(m_path, line, token, lineNumber);
292 if (!(lineStream >> pFeatureRecord->apt_def_symbol_num))
294 throw_parse_error(m_path, line, token, lineNumber);
296 if (pFeatureRecord->apt_def_symbol_num == -1)
298 if (!(lineStream >> pFeatureRecord->apt_def_resize_factor))
300 throw_parse_error(m_path, line, token, lineNumber);
305 if (!(lineStream >> polarity))
307 throw_parse_error(m_path, line, token, lineNumber);
311 case 'P': pFeatureRecord->polarity = Polarity::Positive;
break;
312 case 'N': pFeatureRecord->polarity = Polarity::Negative;
break;
313 default: throw_parse_error(m_path, line, token, lineNumber);
316 if (!(lineStream >> pFeatureRecord->dcode))
318 throw_parse_error(m_path, line, token, lineNumber);
321 if (!(lineStream >> pFeatureRecord->orient_def))
323 throw_parse_error(m_path, line, token, lineNumber);
326 std::string attrIdString;
327 lineStream >> attrIdString;
329 if (!pFeatureRecord->ParseAttributeLookupTable(attrIdString))
331 throw_parse_error(m_path, line, token, lineNumber);
334 m_featureRecords.push_back(pFeatureRecord);
336 else if (line.find(FeatureRecord::TEXT_TOKEN) == 0)
339 if (!(lineStream >> token) || token != FeatureRecord::TEXT_TOKEN)
341 throw_parse_error(m_path, line, token, lineNumber);
344 auto pFeatureRecord = std::make_shared<FeatureRecord>();
345 pFeatureRecord->type = FeatureRecord::Type::Text;
347 if (!(lineStream >> pFeatureRecord->x))
349 throw_parse_error(m_path, line, token, lineNumber);
352 if (!(lineStream >> pFeatureRecord->y))
354 throw_parse_error(m_path, line, token, lineNumber);
357 if (!(lineStream >> pFeatureRecord->font))
359 throw_parse_error(m_path, line, token, lineNumber);
363 if (!(lineStream >> polarity))
365 throw_parse_error(m_path, line, token, lineNumber);
369 case 'P': pFeatureRecord->polarity = Polarity::Positive;
break;
370 case 'N': pFeatureRecord->polarity = Polarity::Negative;
break;
371 default: throw_parse_error(m_path, line, token, lineNumber);
374 if (!(lineStream >> pFeatureRecord->orient_def))
376 throw_parse_error(m_path, line, token, lineNumber);
379 if (pFeatureRecord->orient_def == 8 ||
380 pFeatureRecord->orient_def == 9)
382 if (!(lineStream >> pFeatureRecord->orient_def_rotation))
384 throw_parse_error(m_path, line, token, lineNumber);
388 if (!(lineStream >> pFeatureRecord->xsize))
390 throw_parse_error(m_path, line, token, lineNumber);
393 if (!(lineStream >> pFeatureRecord->ysize))
395 throw_parse_error(m_path, line, token, lineNumber);
398 if (!(lineStream >> pFeatureRecord->width_factor))
400 throw_parse_error(m_path, line, token, lineNumber);
403 if (!(lineStream >> std::quoted(pFeatureRecord->text,
'\'')))
405 throw_parse_error(m_path, line, token, lineNumber);
408 if (!(lineStream >> pFeatureRecord->version))
410 throw_parse_error(m_path, line, token, lineNumber);
413 std::string attrIdString;
414 lineStream >> attrIdString;
416 if (!pFeatureRecord->ParseAttributeLookupTable(attrIdString))
418 throw_parse_error(m_path, line, token, lineNumber);
421 m_featureRecords.push_back(pFeatureRecord);
423 else if (line.find(FeatureRecord::ARC_TOKEN) == 0)
426 if (!(lineStream >> token) || token != FeatureRecord::ARC_TOKEN)
428 throw_parse_error(m_path, line, token, lineNumber);
431 auto pFeatureRecord = std::make_shared<FeatureRecord>();
432 pFeatureRecord->type = FeatureRecord::Type::Arc;
434 if (!(lineStream >> pFeatureRecord->xs))
436 throw_parse_error(m_path, line, token, lineNumber);
439 if (!(lineStream >> pFeatureRecord->ys))
441 throw_parse_error(m_path, line, token, lineNumber);
444 if (!(lineStream >> pFeatureRecord->xe))
446 throw_parse_error(m_path, line, token, lineNumber);
449 if (!(lineStream >> pFeatureRecord->ye))
451 throw_parse_error(m_path, line, token, lineNumber);
454 if (!(lineStream >> pFeatureRecord->xc))
456 throw_parse_error(m_path, line, token, lineNumber);
459 if (!(lineStream >> pFeatureRecord->yc))
461 throw_parse_error(m_path, line, token, lineNumber);
465 if (!(lineStream >> pFeatureRecord->sym_num))
467 throw_parse_error(m_path, line, token, lineNumber);
471 if (!(lineStream >> polarity))
473 throw_parse_error(m_path, line, token, lineNumber);
477 case 'P': pFeatureRecord->polarity = Polarity::Positive;
break;
478 case 'N': pFeatureRecord->polarity = Polarity::Negative;
break;
479 default: throw_parse_error(m_path, line, token, lineNumber);
482 if (!(lineStream >> pFeatureRecord->dcode))
484 throw_parse_error(m_path, line, token, lineNumber);
488 if (!(lineStream >> cw))
490 throw_parse_error(m_path, line, token, lineNumber);
494 case 'Y': pFeatureRecord->cw =
true;
break;
495 case 'N': pFeatureRecord->cw =
false;
break;
496 default: throw_parse_error(m_path, line, token, lineNumber);
499 std::string attrIdString;
500 lineStream >> attrIdString;
502 if (!pFeatureRecord->ParseAttributeLookupTable(attrIdString))
504 throw_parse_error(m_path, line, token, lineNumber);
507 m_featureRecords.push_back(pFeatureRecord);
509 else if (line.find(FeatureRecord::BARCODE_TOKEN) == 0)
512 if (!(lineStream >> token) || token != FeatureRecord::BARCODE_TOKEN)
514 throw_parse_error(m_path, line, token, lineNumber);
517 auto pFeatureRecord = std::make_shared<FeatureRecord>();
518 pFeatureRecord->type = FeatureRecord::Type::Barcode;
530 m_featureRecords.push_back(pFeatureRecord);
532 else if (line.find(FeatureRecord::SURFACE_START_TOKEN) == 0 &&
533 line.size() > 1 && line[1] ==
' ')
536 if (!(lineStream >> token) || token != FeatureRecord::SURFACE_START_TOKEN)
538 throw_parse_error(m_path, line, token, lineNumber);
541 pCurrentFeatureRecord = std::make_shared<FeatureRecord>();
542 pCurrentFeatureRecord->type = FeatureRecord::Type::Surface;
545 if (!(lineStream >> polarity))
547 throw_parse_error(m_path, line, token, lineNumber);
551 case 'P': pCurrentFeatureRecord->polarity = Polarity::Positive;
break;
552 case 'N': pCurrentFeatureRecord->polarity = Polarity::Negative;
break;
553 default: throw_parse_error(m_path, line, token, lineNumber);
556 if (!(lineStream >> pCurrentFeatureRecord->dcode))
558 throw_parse_error(m_path, line, token, lineNumber);
561 std::string attrIdString;
562 lineStream >> attrIdString;
564 if (!pCurrentFeatureRecord->ParseAttributeLookupTable(attrIdString))
566 throw_parse_error(m_path, line, token, lineNumber);
569 else if (line.find(FeatureRecord::SURFACE_END_TOKEN) == 0)
572 if (!(lineStream >> token) || token != FeatureRecord::SURFACE_END_TOKEN)
574 throw_parse_error(m_path, line, token, lineNumber);
577 if (pCurrentFeatureRecord !=
nullptr)
579 m_featureRecords.push_back(pCurrentFeatureRecord);
580 pCurrentFeatureRecord.reset();
584 throw_parse_error(m_path, line, token, lineNumber);
587 else if (line.find(ContourPolygon::BEGIN_RECORD_TOKEN) == 0)
590 if (!(lineStream >> token))
592 throw_parse_error(m_path, line, token, lineNumber);
595 if (token != ContourPolygon::BEGIN_RECORD_TOKEN)
597 throw_parse_error(m_path, line, token, lineNumber);
600 pCurrentContourPolygon = std::make_shared<ContourPolygon>();
602 if (!(lineStream >> pCurrentContourPolygon->xStart))
604 throw_parse_error(m_path, line, token, lineNumber);
607 if (!(lineStream >> pCurrentContourPolygon->yStart))
609 throw_parse_error(m_path, line, token, lineNumber);
612 if (!(lineStream >> token))
614 throw_parse_error(m_path, line, token, lineNumber);
617 if (token == ContourPolygon::ISLAND_TYPE_TOKEN)
619 pCurrentContourPolygon->type = ContourPolygon::Type::Island;
621 else if (token == ContourPolygon::HOLE_TYPE_TOKEN)
623 pCurrentContourPolygon->type = ContourPolygon::Type::Hole;
627 throw_parse_error(m_path, line, token, lineNumber);
630 else if (line.find(ContourPolygon::END_RECORD_TOKEN) == 0)
633 if (!(lineStream >> token))
635 throw_parse_error(m_path, line, token, lineNumber);
638 if (token != ContourPolygon::END_RECORD_TOKEN)
640 throw_parse_error(m_path, line, token, lineNumber);
643 if (pCurrentFeatureRecord !=
nullptr)
645 pCurrentFeatureRecord->m_contourPolygons.push_back(pCurrentContourPolygon);
646 pCurrentContourPolygon.reset();
650 throw_parse_error(m_path, line, token, lineNumber);
653 else if (line.find(ContourPolygon::PolygonPart::ARC_RECORD_TOKEN) == 0)
656 if (!(lineStream >> token))
658 throw_parse_error(m_path, line, token, lineNumber);
661 if (token != ContourPolygon::PolygonPart::ARC_RECORD_TOKEN)
663 throw_parse_error(m_path, line, token, lineNumber);
666 auto pPolygonPart = std::make_shared<ContourPolygon::PolygonPart>();
667 pPolygonPart->type = ContourPolygon::PolygonPart::Type::Arc;
669 if (!(lineStream >> pPolygonPart->endX))
671 throw_parse_error(m_path, line, token, lineNumber);
674 if (!(lineStream >> pPolygonPart->endY))
676 throw_parse_error(m_path, line, token, lineNumber);
679 if (!(lineStream >> pPolygonPart->xCenter))
681 throw_parse_error(m_path, line, token, lineNumber);
684 if (!(lineStream >> pPolygonPart->yCenter))
686 throw_parse_error(m_path, line, token, lineNumber);
689 if (!(lineStream >> token))
691 throw_parse_error(m_path, line, token, lineNumber);
694 if (token ==
"y" || token ==
"Y")
696 pPolygonPart->isClockwise =
true;
698 else if (token ==
"n" || token ==
"N")
700 pPolygonPart->isClockwise =
false;
704 throw_parse_error(m_path, line, token, lineNumber);
707 if (pCurrentContourPolygon !=
nullptr)
709 pCurrentContourPolygon->m_polygonParts.push_back(pPolygonPart);
713 throw_parse_error(m_path, line, token, lineNumber);
716 else if (line.find(ContourPolygon::PolygonPart::SEGMENT_RECORD_TOKEN) == 0)
719 if (!(lineStream >> token))
721 throw_parse_error(m_path, line, token, lineNumber);
724 if (token != ContourPolygon::PolygonPart::SEGMENT_RECORD_TOKEN)
726 throw_parse_error(m_path, line, token, lineNumber);
729 auto pPolygonPart = std::make_shared<ContourPolygon::PolygonPart>();
730 pPolygonPart->type = ContourPolygon::PolygonPart::Type::Segment;
732 if (!(lineStream >> pPolygonPart->endX))
734 throw_parse_error(m_path, line, token, lineNumber);
737 if (!(lineStream >> pPolygonPart->endY))
739 throw_parse_error(m_path, line, token, lineNumber);
742 if (pCurrentContourPolygon !=
nullptr)
744 pCurrentContourPolygon->m_polygonParts.push_back(pPolygonPart);
748 throw_parse_error(m_path, line, token, lineNumber);
754 parse_info pi(m_path, line, lineNumber);
755 logwarn(pi.toString(
"unrecognized record line in features file:"));
761 if (pCurrentFeatureRecord !=
nullptr)
764 m_featureRecords.push_back(pCurrentFeatureRecord);
765 pCurrentFeatureRecord.reset();
768 featuresFile.close();
770 catch (parse_error& pe)
772 auto m = pe.toString(
"Parse Error:");
774 featuresFile.close();
777 catch (std::exception& e)
779 parse_info pi(m_path, line, lineNumber);
780 const auto m = pi.toString();
781 logexception_msg(e, m);
782 featuresFile.close();
789 std::string FeaturesFile::GetUnits()
const
794 std::filesystem::path FeaturesFile::GetPath()
799 std::filesystem::path FeaturesFile::GetDirectory()
804 int FeaturesFile::GetNumFeatures()
const
806 return m_numFeatures;
809 unsigned int FeaturesFile::GetId()
const
814 const SymbolName::StringMap& FeaturesFile::GetSymbolNamesByName()
const
816 return m_symbolNamesByName;
819 const FeaturesFile::FeatureRecord::Vector& FeaturesFile::GetFeatureRecords()
const
821 return m_featureRecords;
824 std::unique_ptr<Odb::Lib::Protobuf::FeaturesFile> FeaturesFile::to_protobuf()
const
826 std::unique_ptr<Odb::Lib::Protobuf::FeaturesFile> pFeaturesFileMessage(
new Odb::Lib::Protobuf::FeaturesFile);
827 pFeaturesFileMessage->set_id(m_id);
828 pFeaturesFileMessage->set_numfeatures(m_numFeatures);
829 pFeaturesFileMessage->set_units(m_units);
830 for (
const auto& pFeatureRecord : m_featureRecords)
832 pFeaturesFileMessage->add_featurerecords()->CopyFrom(*pFeatureRecord->to_protobuf());
834 for (
const auto& kvSymbolName : m_symbolNamesByName)
836 (*pFeaturesFileMessage->mutable_symbolnamesbyname())[kvSymbolName.first] = *kvSymbolName.second->to_protobuf();
838 return pFeaturesFileMessage;
841 void FeaturesFile::from_protobuf(
const Odb::Lib::Protobuf::FeaturesFile& message)
844 m_numFeatures = message.numfeatures();
845 m_units = message.units();
846 for (
const auto& featureRecordMessage : message.featurerecords())
848 std::shared_ptr<FeatureRecord> pFeatureRecord(
new FeatureRecord);
849 pFeatureRecord->from_protobuf(featureRecordMessage);
850 m_featureRecords.push_back(pFeatureRecord);
852 for (
const auto& kvSymbolNameMessage : message.symbolnamesbyname())
854 auto pSymbolName = std::make_shared<SymbolName>();
855 pSymbolName->from_protobuf(kvSymbolNameMessage.second);
856 m_symbolNamesByName[kvSymbolNameMessage.first] = pSymbolName;
860 bool FeaturesFile::Save(std::ostream& os)
865 FeaturesFile::FeatureRecord::~FeatureRecord()
867 m_contourPolygons.clear();
870 const ContourPolygon::Vector& FeaturesFile::FeatureRecord::GetContourPolygons()
const
872 return m_contourPolygons;
875 std::unique_ptr<Odb::Lib::Protobuf::FeaturesFile::FeatureRecord> Odb::Lib::FileModel::Design::FeaturesFile::FeatureRecord::to_protobuf()
const
877 std::unique_ptr<Odb::Lib::Protobuf::FeaturesFile::FeatureRecord> pFeatureRecordMessage(
new Odb::Lib::Protobuf::FeaturesFile::FeatureRecord);
878 pFeatureRecordMessage->set_apt_def_resize_factor(apt_def_resize_factor);
879 pFeatureRecordMessage->set_xc(xc);
880 pFeatureRecordMessage->set_yc(yc);
881 pFeatureRecordMessage->set_cw(cw);
882 pFeatureRecordMessage->set_font(font);
883 pFeatureRecordMessage->set_xsize(xsize);
884 pFeatureRecordMessage->set_ysize(ysize);
885 pFeatureRecordMessage->set_width_factor(width_factor);
886 pFeatureRecordMessage->set_text(text);
887 pFeatureRecordMessage->set_version(version);
888 pFeatureRecordMessage->set_sym_num(sym_num);
889 pFeatureRecordMessage->set_polarity(
static_cast<Odb::Lib::Protobuf::Polarity
>(polarity));
890 pFeatureRecordMessage->set_dcode(dcode);
891 pFeatureRecordMessage->set_id(
id);
892 pFeatureRecordMessage->set_orient_def(orient_def);
893 pFeatureRecordMessage->set_orient_def_rotation(orient_def_rotation);
894 pFeatureRecordMessage->set_type(
static_cast<Odb::Lib::Protobuf::FeaturesFile::FeatureRecord::Type
>(type));
895 pFeatureRecordMessage->set_xs(xs);
896 pFeatureRecordMessage->set_ys(ys);
897 pFeatureRecordMessage->set_xe(xe);
898 pFeatureRecordMessage->set_ye(ye);
899 pFeatureRecordMessage->set_x(x);
900 pFeatureRecordMessage->set_y(y);
901 pFeatureRecordMessage->set_apt_def_symbol_num(apt_def_symbol_num);
902 for (
const auto& pContourPolygon : m_contourPolygons)
904 pFeatureRecordMessage->add_contourpolygons()->CopyFrom(*pContourPolygon->to_protobuf());
906 for (
const auto& kvAttributeAssignment : m_attributeLookupTable)
908 (*pFeatureRecordMessage->mutable_attributelookuptable())[kvAttributeAssignment.first] = kvAttributeAssignment.second;
910 return pFeatureRecordMessage;
913 void Odb::Lib::FileModel::Design::FeaturesFile::FeatureRecord::from_protobuf(
const Odb::Lib::Protobuf::FeaturesFile::FeatureRecord& message)
915 apt_def_resize_factor = message.apt_def_resize_factor();
919 font = message.font();
920 xsize = message.xsize();
921 ysize = message.ysize();
922 width_factor = message.width_factor();
923 text = message.text();
924 version = message.version();
925 sym_num = message.sym_num();
926 polarity =
static_cast<Polarity
>(message.polarity());
927 dcode = message.dcode();
929 orient_def = message.orient_def();
930 orient_def_rotation = message.orient_def_rotation();
931 type =
static_cast<Type
>(message.type());
938 apt_def_symbol_num = message.apt_def_symbol_num();
939 for (
const auto& contourPolygonMessage : message.contourpolygons())
941 std::shared_ptr<ContourPolygon> pContourPolygon(
new ContourPolygon);
942 pContourPolygon->from_protobuf(contourPolygonMessage);
943 m_contourPolygons.push_back(pContourPolygon);
945 for (
const auto& kvAttributeAssignment : message.attributelookuptable())
947 m_attributeLookupTable[kvAttributeAssignment.first] = kvAttributeAssignment.second;