bool ccGBLSensor::computeAutoParameters(CCLib::GenericCloud* theCloud) { assert(theCloud); if (!theCloud) { //invalid input parameter return false; } std::vector<bool> nonEmptyAnglesYaw,nonEmptyAnglesPitch; try { nonEmptyAnglesYaw.resize(360,false); nonEmptyAnglesPitch.resize(360,false); } catch(std::bad_alloc) { //not enough memory return false; } //force no shift for auto search (we'll fix this later if necessary) m_yawAnglesAreShifted = false; m_pitchAnglesAreShifted = false; unsigned pointCount = theCloud->size(); PointCoordinateType minPitch = 0, maxPitch = 0, minYaw = 0, maxYaw = 0; PointCoordinateType maxDepth = 0; { //first project all points to compute the (yaw,ptich) ranges theCloud->placeIteratorAtBegining(); for (unsigned i=0; i<pointCount; ++i) { const CCVector3* P = theCloud->getNextPoint(); CCVector2 Q; PointCoordinateType depth; //Q.x and Q.y are inside [-pi;pi] by default (result of atan2) projectPoint(*P,Q,depth,m_activeIndex); //yaw int angleYaw = static_cast<int>(Q.x * CC_RAD_TO_DEG); assert(angleYaw >= -180 && angleYaw <= 180); if (angleYaw == 180) //360 degrees warp angleYaw = -180; nonEmptyAnglesYaw[180 + angleYaw] = true; if (i != 0) { if (minYaw > Q.x) minYaw = Q.x; else if (maxYaw < Q.x) maxYaw = Q.x; } else { minYaw = maxYaw = Q.x; } //pitch int anglePitch = static_cast<int>(Q.y * CC_RAD_TO_DEG); assert(anglePitch >= -180 && anglePitch <= 180); if (anglePitch == 180) anglePitch = -180; nonEmptyAnglesPitch[180 + anglePitch] = true; if (i != 0) { if (minPitch > Q.y) minPitch = Q.y; else if (maxPitch < Q.y) maxPitch = Q.y; } else { minPitch = maxPitch = Q.y; } if (depth > maxDepth) maxDepth = depth; } } Interval bestEmptyPartYaw = Interval::FindBiggest<bool>(nonEmptyAnglesYaw,false,true); Interval bestEmptyPartPitch = Interval::FindBiggest<bool>(nonEmptyAnglesPitch,false,true); m_yawAnglesAreShifted = (bestEmptyPartYaw.start != 0 && bestEmptyPartYaw.span > 1 && bestEmptyPartYaw.start + bestEmptyPartYaw.span < 360); m_pitchAnglesAreShifted = (bestEmptyPartPitch.start != 0 && bestEmptyPartPitch.span > 1 && bestEmptyPartPitch.start + bestEmptyPartPitch.span < 360); if (m_yawAnglesAreShifted || m_pitchAnglesAreShifted) { //we re-project all the points in order to update the boundaries! theCloud->placeIteratorAtBegining(); for (unsigned i = 0; i<pointCount; ++i) { const CCVector3 *P = theCloud->getNextPoint(); CCVector2 Q; PointCoordinateType depth; projectPoint(*P,Q,depth,m_activeIndex); if (i != 0) { if (minYaw > Q.x) minYaw = Q.x; else if (maxYaw < Q.x) maxYaw = Q.x; if (minPitch > Q.y) minPitch = Q.y; else if (maxPitch < Q.y) maxPitch = Q.y; } else { minYaw = maxYaw = Q.x; minPitch = maxPitch = Q.y; } } } setYawRange(minYaw,maxYaw); setPitchRange(minPitch,maxPitch); setSensorRange(maxDepth); return true; }
void InstrumentTemplate::read(const QDomElement& de) { bool customDrumset = false; staves = 1; for (int i = 0; i < MAX_STAVES; ++i) { clefIdx[i] = CLEF_INVALID; staffLines[i] = -1; smallStaff[i] = false; bracket[i] = NO_BRACKET; bracketSpan[i] = 0; barlineSpan[i] = 0; } minPitchA = 0; maxPitchA = 127; minPitchP = 0; maxPitchP = 127; transpose.diatonic = 0; transpose.chromatic = 0; useDrumset = false; for (QDomElement e = de.firstChildElement(); !e.isNull(); e = e.nextSiblingElement()) { const QString& tag(e.tagName()); const QString& val(e.text()); if (tag == "name" || tag == "longName") { // "name" is obsolete int pos = e.attribute("pos", "0").toInt(); QString longName = Xml::htmlToString(e); longNames.append(StaffName(longName, pos)); } else if (tag == "short-name" || tag == "shortName") { // "short-name" is obsolete int pos = e.attribute("pos", "0").toInt(); QString shortName = Xml::htmlToString(e); shortNames.append(StaffName(shortName, pos)); } else if (tag == "description") trackName = val; else if (tag == "extended") extended = true; else if (tag == "staves") { staves = val.toInt(); bracketSpan[0] = staves; barlineSpan[0] = staves; } else if (tag == "clef") { int idx = readStaffIdx(e); bool ok; int i = val.toInt(&ok); if (!ok) { ClefType ct = Clef::clefType(val); clefIdx[idx] = ct; } else clefIdx[idx] = ClefType(i); } else if (tag == "stafflines") { int idx = readStaffIdx(e); staffLines[idx] = val.toInt(); } else if (tag == "smallStaff") { int idx = readStaffIdx(e); smallStaff[idx] = val.toInt(); } else if (tag == "bracket") { int idx = readStaffIdx(e); bracket[idx] = BracketType(val.toInt()); } else if (tag == "bracketSpan") { int idx = readStaffIdx(e); bracketSpan[idx] = val.toInt(); } else if (tag == "barlineSpan") { int idx = readStaffIdx(e); barlineSpan[idx] = val.toInt(); } else if (tag == "Tablature") { tablature = new Tablature; tablature->read(e); } else if (tag == "aPitchRange") setPitchRange(val, &minPitchA, &maxPitchA); else if (tag == "pPitchRange") setPitchRange(val, &minPitchP, &maxPitchP); else if (tag == "transposition") { // obsolete transpose.chromatic = val.toInt(); transpose.diatonic = chromatic2diatonic(val.toInt()); } else if (tag == "transposeChromatic") transpose.chromatic = val.toInt(); else if (tag == "transposeDiatonic") transpose.diatonic = val.toInt(); else if (tag == "drumset") useDrumset = val.toInt(); else if (tag == "Drum") { // if we see on of this tags, a custom drumset will // be created if (drumset == 0) drumset = new Drumset(*smDrumset); if (!customDrumset) { drumset->clear(); customDrumset = true; } drumset->load(e); } else if (tag == "MidiAction") { NamedEventList a; a.read(e); midiActions.append(a); } else if (tag == "channel") { Channel a; a.read(e); channel.append(a); } else if (tag == "Articulation") { MidiArticulation a; a.read(e); int n = articulation.size(); int i; for(i = 0; i < n; ++i) { if (articulation[i].name == a.name) { articulation[i] = a; break; } } if (i == n) articulation.append(a); } else if (tag == "stafftype") { if (val == "tablature") useTablature = true; else { qDebug("unknown stafftype <%s>\n", qPrintable(val)); domError(e); } } else if (tag == "init") { InstrumentTemplate* ttt = searchTemplate(val); if (ttt) { // qDebug("Instrument template init <%s> from <%s>\n", qPrintable(trackName), qPrintable(ttt->trackName)); init(*ttt); } else qDebug("Instrument template <%s> not found\n", qPrintable(val)); } else domError(e); } // // check bar line spans // int barLine = 0; for (int i = 0; i < staves; ++i) { int bls = barlineSpan[i]; if (barLine) { if (bls) barlineSpan[i] = 0; } else { if (bls == 0) { bls = 1; barlineSpan[i] = 1; } barLine = bls; } --barLine; } for (int i = 0; i < MAX_STAVES; ++i) { if (clefIdx[i] == CLEF_INVALID) clefIdx[i] = CLEF_G; if (staffLines[i] == -1) staffLines[i] = 5; } if (channel.isEmpty()) { Channel a; a.chorus = 0; a.reverb = 0; a.name = "normal"; a.program = 0; a.bank = 0; a.volume = 100; a.pan = 60; channel.append(a); } if (useDrumset) { if (channel[0].bank == 0) channel[0].bank = 128; channel[0].updateInitList(); } if (trackName.isEmpty() && !longNames.isEmpty()) trackName = parseInstrName(longNames[0].name); }