in core/indigo-core/molecule/src/molfile_loader.cpp [1574:1840]
void MolfileLoader::_read3dFeature2000()
{
// read 3D feature ID (see MDL ctfile documentation)
int feature_id = _scanner.readIntFix(3);
_scanner.skipLine();
Molecule3dConstraints* constraints = &_qmol->spatial_constraints;
if (constraints->end() == 0)
constraints->init();
switch (feature_id)
{
case -1: // point defined by 2 points and distance
{
std::unique_ptr<Molecule3dConstraints::PointByDistance> constr = std::make_unique<Molecule3dConstraints::PointByDistance>();
_scanner.skip(6);
constr->beg_id = _scanner.readIntFix(3) - 1;
constr->end_id = _scanner.readIntFix(3) - 1;
constr->distance = _scanner.readFloatFix(10);
_scanner.skipLine();
constraints->add(constr.release());
break;
}
case -2: // point defined by 2 points and percentage
{
std::unique_ptr<Molecule3dConstraints::PointByPercentage> constr = std::make_unique<Molecule3dConstraints::PointByPercentage>();
_scanner.skip(6);
constr->beg_id = _scanner.readIntFix(3) - 1;
constr->end_id = _scanner.readIntFix(3) - 1;
constr->percentage = _scanner.readFloatFix(10);
_scanner.skipLine();
constraints->add(constr.release());
break;
}
case -3: // point defined by point, normal line, and distance
{
std::unique_ptr<Molecule3dConstraints::PointByNormale> constr = std::make_unique<Molecule3dConstraints::PointByNormale>();
_scanner.skip(6);
constr->org_id = _scanner.readIntFix(3) - 1;
constr->norm_id = _scanner.readIntFix(3) - 1;
constr->distance = _scanner.readFloatFix(10);
_scanner.skipLine();
constraints->add(constr.release());
break;
}
case -4: // line defined by 2 or more points (best fit line if more than 2 points)
{
std::unique_ptr<Molecule3dConstraints::BestFitLine> constr = std::make_unique<Molecule3dConstraints::BestFitLine>();
_scanner.skip(6);
int amount = _scanner.readIntFix(3);
if (amount < 2)
throw Error("invalid points amount in M $3D-4 feature");
constr->max_deviation = _scanner.readFloatFix(10);
_scanner.skipLine();
_scanner.skip(6);
while (amount-- > 0)
constr->point_ids.push(_scanner.readIntFix(3) - 1);
_scanner.skipLine();
constraints->add(constr.release());
break;
}
case -5: // plane defined by 3 or more points (best fit line if more than 3 points)
{
std::unique_ptr<Molecule3dConstraints::BestFitPlane> constr = std::make_unique<Molecule3dConstraints::BestFitPlane>();
_scanner.skip(6);
int amount = _scanner.readIntFix(3);
if (amount < 3)
throw Error("invalid points amount in M $3D-5 feature");
constr->max_deviation = _scanner.readFloatFix(10);
_scanner.skipLine();
_scanner.skip(6);
while (amount-- > 0)
constr->point_ids.push(_scanner.readIntFix(3) - 1);
_scanner.skipLine();
constraints->add(constr.release());
break;
}
case -6: // plane defined by point and line
{
std::unique_ptr<Molecule3dConstraints::PlaneByPoint> constr = std::make_unique<Molecule3dConstraints::PlaneByPoint>();
_scanner.skip(6);
constr->point_id = _scanner.readIntFix(3) - 1;
constr->line_id = _scanner.readIntFix(3) - 1;
_scanner.skipLine();
constraints->add(constr.release());
break;
}
case -7: // centroid defined by points
{
std::unique_ptr<Molecule3dConstraints::Centroid> constr = std::make_unique<Molecule3dConstraints::Centroid>();
_scanner.skip(6);
int amount = _scanner.readIntFix(3);
if (amount < 1)
throw Error("invalid amount of points for centroid: %d", amount);
_scanner.skipLine();
_scanner.skip(6);
while (amount-- > 0)
constr->point_ids.push(_scanner.readIntFix(3) - 1);
_scanner.skipLine();
constraints->add(constr.release());
break;
}
case -8: // normal line defined by point and plane
{
std::unique_ptr<Molecule3dConstraints::Normale> constr = std::make_unique<Molecule3dConstraints::Normale>();
_scanner.skip(6);
constr->point_id = _scanner.readIntFix(3) - 1;
constr->plane_id = _scanner.readIntFix(3) - 1;
_scanner.skipLine();
constraints->add(constr.release());
break;
}
case -9: // distance defined by 2 points and range
{
std::unique_ptr<Molecule3dConstraints::DistanceByPoints> constr = std::make_unique<Molecule3dConstraints::DistanceByPoints>();
_scanner.skip(6);
constr->beg_id = _scanner.readIntFix(3) - 1;
constr->end_id = _scanner.readIntFix(3) - 1;
constr->bottom = _scanner.readFloatFix(10);
constr->top = _scanner.readFloatFix(10);
_scanner.skipLine();
constraints->add(constr.release());
break;
}
case -10: // distance defined by point, line and range
{
std::unique_ptr<Molecule3dConstraints::DistanceByLine> constr = std::make_unique<Molecule3dConstraints::DistanceByLine>();
_scanner.skip(6);
constr->point_id = _scanner.readIntFix(3) - 1;
constr->line_id = _scanner.readIntFix(3) - 1;
constr->bottom = _scanner.readFloatFix(10);
constr->top = _scanner.readFloatFix(10);
_scanner.skipLine();
constraints->add(constr.release());
break;
}
case -11: // distance defined by point, plane and range
{
std::unique_ptr<Molecule3dConstraints::DistanceByPlane> constr = std::make_unique<Molecule3dConstraints::DistanceByPlane>();
_scanner.skip(6);
constr->point_id = _scanner.readIntFix(3) - 1;
constr->plane_id = _scanner.readIntFix(3) - 1;
constr->bottom = _scanner.readFloatFix(10);
constr->top = _scanner.readFloatFix(10);
_scanner.skipLine();
constraints->add(constr.release());
break;
}
case -12: // angle defined by 3 points and range
{
std::unique_ptr<Molecule3dConstraints::AngleByPoints> constr = std::make_unique<Molecule3dConstraints::AngleByPoints>();
_scanner.skip(6);
constr->point1_id = _scanner.readIntFix(3) - 1;
constr->point2_id = _scanner.readIntFix(3) - 1;
constr->point3_id = _scanner.readIntFix(3) - 1;
constr->bottom = (float)(_scanner.readFloatFix(10) * M_PI / 180);
constr->top = (float)(_scanner.readFloatFix(10) * M_PI / 180);
_scanner.skipLine();
constraints->add(constr.release());
break;
}
case -13: // angle defined by 2 lines and range
{
std::unique_ptr<Molecule3dConstraints::AngleByLines> constr = std::make_unique<Molecule3dConstraints::AngleByLines>();
_scanner.skip(6);
constr->line1_id = _scanner.readIntFix(3) - 1;
constr->line2_id = _scanner.readIntFix(3) - 1;
constr->bottom = (float)(_scanner.readFloatFix(10) * M_PI / 180);
constr->top = (float)(_scanner.readFloatFix(10) * M_PI / 180);
_scanner.skipLine();
constraints->add(constr.release());
break;
}
case -14: // angles defined by 2 planes and range
{
std::unique_ptr<Molecule3dConstraints::AngleByPlanes> constr = std::make_unique<Molecule3dConstraints::AngleByPlanes>();
_scanner.skip(6);
constr->plane1_id = _scanner.readIntFix(3) - 1;
constr->plane2_id = _scanner.readIntFix(3) - 1;
constr->bottom = (float)(_scanner.readFloatFix(10) * M_PI / 180);
constr->top = (float)(_scanner.readFloatFix(10) * M_PI / 180);
_scanner.skipLine();
constraints->add(constr.release());
break;
}
case -15: // dihedral angle defined by 4 points
{
std::unique_ptr<Molecule3dConstraints::AngleDihedral> constr = std::make_unique<Molecule3dConstraints::AngleDihedral>();
_scanner.skip(6);
constr->point1_id = _scanner.readIntFix(3) - 1;
constr->point2_id = _scanner.readIntFix(3) - 1;
constr->point3_id = _scanner.readIntFix(3) - 1;
constr->point4_id = _scanner.readIntFix(3) - 1;
constr->bottom = (float)(_scanner.readFloatFix(10) * M_PI / 180);
constr->top = (float)(_scanner.readFloatFix(10) * M_PI / 180);
_scanner.skipLine();
constraints->add(constr.release());
break;
}
case -16: // exclusion sphere defines by points and distance
{
std::unique_ptr<Molecule3dConstraints::ExclusionSphere> constr = std::make_unique<Molecule3dConstraints::ExclusionSphere>();
int allowed_atoms_amount;
Array<int> allowed_atoms;
_scanner.skip(6);
constr->center_id = _scanner.readIntFix(3) - 1;
constr->allow_unconnected = (_scanner.readIntFix(3) != 0);
allowed_atoms_amount = _scanner.readIntFix(3);
constr->radius = (float)(_scanner.readFloatFix(10));
if (allowed_atoms_amount > 0)
{
_scanner.skipLine();
_scanner.skip(6);
while (allowed_atoms_amount-- > 0)
constr->allowed_atoms.push(_scanner.readIntFix(3) - 1);
}
_scanner.skipLine();
constraints->add(constr.release());
break;
}
case -17: // fixed atoms
{
_scanner.skip(6);
int amount = _scanner.readIntFix(3);
_scanner.skipLine();
_scanner.skip(6);
while (amount-- > 0)
_qmol->fixed_atoms.push(_scanner.readIntFix(3) - 1);
_scanner.skipLine();
break;
}
default:
throw Error("unknown 3D feature in createFromMolfile: %d", feature_id);
}
}