Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SDF geometries support #391

Merged
merged 34 commits into from
May 25, 2018
Merged

SDF geometries support #391

merged 34 commits into from
May 25, 2018

Conversation

karjonas
Copy link
Contributor

A new geometry type called ExtendedSDFGeometries is added. This PR also includes a thickness smoothing algorithm used when loading morphologies. It can be activated by adding '--dampen-branch-thickness-changerate true' when running Brayns. To create SDF geometries when loading a morphology you add '--use-sdf-geometries true'

Copy link

@rdumusc rdumusc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Look pretty good in general! Some unit tests would be nice too :-)

@@ -42,6 +42,7 @@ set(BRAYNSCOMMON_PUBLIC_HEADERS
geometry/Cylinder.h
geometry/Sphere.h
geometry/TrianglesMesh.h
geometry/SDFGeometry.h
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alphabetical order

@@ -66,7 +81,7 @@ class MorphologyLoader::Impl
model.getCylinders(),
model.getCones(),
model.getTrianglesMeshes(),
model.getBounds());
model.getBounds(), model);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmmm, looks like it should only take model as a parameter then. But maybe there was a reason for not passing the model before..?

* @param compartmentReport Compartment report to map to the morphology
* @param scene Scene to which the morphology should be loaded into
* @return True if the loading was successful, false otherwise
* @brief _connectSDFSomaChildren Creates an SDF soma by adding and
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rm "@brief _connectSDFSomaChildren"

inline SDFGeometry createSDFConePill(const Vector3f& p0, const Vector3f& p1,
const float radiusBottom,
const float radiusTip,
const float sigmoid = false)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since ConePill and ConePillSigmoid are two separate SDFTypes, it would probably be more consistent to have a createSDFConePillSigmoid() function.

In general, bool parameters are not ideal because they are not self-describing when reading the calling code.
In:
createSDFConePill(somaPosition, sample, somaRadius * 0.5f, radiusEnd, true);
it is not obvious what true means.

}

/**
* @brief _finalizeSDFGeometries Calculates all neighbours and adds the
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rm "@brief _finalizeSDFGeometries"

vec2f t = make_vec2f(max(tmin.x, tmin.y), max(tmin.x, tmin.z));
t0 = max(t.x, t.y);
t = make_vec2f(min(tmax.x, tmax.y), min(tmax.x, tmax.z));
t1 = min(t.x, t.y);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

n * const

std::vector<size_t> _SDFNeighboursFlat;
std::vector<std::vector<size_t>> _SDFNeighbours;
std::vector<SDFGeometry> _SDFGeometries;
bool _SDFGeometriesDirty{false};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure, but that's a lot of additions to the Model class, could maybe go into a separate SDF class instanced here..?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was wondering in general if this should be in the core at all or rather be a 'real' plugin? Maybe not now, but latest when the circuit loader and friends are moved to a plugin, this shall move as well.

const std::vector<size_t>& neighbourIndices);

/** Builds the flat list of neighbours for the SDF geometries */
void buildSDFGeometryNeighboursFlat();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this have to be public? Who should call it, why and when?

@param neighbourIndices Indices of the neighbours
*/
void setSDFGeometryNeighbours(size_t geometryIdx,
const std::vector<size_t>& neighbourIndices);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about renaming this function to updateSDFGeometryNeighbours? They are already set in addSDFGeometry() if I'm correct.

Also, this may be a stupid question, but where do I find the geometryIdx to pass to this function?

Adds a SDFGeometry to the scene
@param materialId Material of the geometry
@param geom Geometry to add
@param neighbours List of global indices of the geometry neighbours
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For people like me who are not familiar with SDF terminology, it would great if you could document what neighbours are used for and how I should compute them.

@karjonas karjonas force-pushed the sdf_geometries branch 2 times, most recently from 677dbe6 to 7682fbe Compare May 24, 2018 10:07
@karjonas
Copy link
Contributor Author

All issues should be fixed now

Copy link
Contributor

@tribal-tec tribal-tec left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good for me otherwise. Maybe trying to use the texture coordinates to support simulation mapping.

_bounds.merge(geom.center + Vector3f(geom.radius));
break;
}
case brayns::SDFType::Pill:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use default: instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a throw on the default case so that you do not forget to set the bounds if you add a new geometry type.

@favreau
Copy link
Member

favreau commented May 24, 2018

Ultra super cool PR! :)

@karjonas
Copy link
Contributor Author

I also added the textures and timestamp variables to the SDF geometries now so we can get the proper simulation colors.

Copy link

@rdumusc rdumusc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 for me, just a few last comments :-)

void Model::updateSDFGeometryNeighbours(
size_t geometryIdx, const std::vector<size_t>& neighbourIndices)
{
_sdfGeometryData.neighbours[geometryIdx] = neighbourIndices;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doesn't this make the geometry dirty?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, fixed

}
default:
throw std::runtime_error("No bounds found for SDF type.");
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would refactor this a bit, moving the logic to get the min/max to the geometry class and keep here only something like:
_bounds.merge(geom.getMin());
_bounds.merge(geom.getMax());
As an added benefit, it lets you unit test independently the geom.getMin/Max() code :-)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I created a function that returns the bounding box.

_sdfGeometryData.neighbours.size());

_sdfGeometryData.neighbours.push_back(neighbourIndices);
_sdfGeometryData.geometries.push_back(geom);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To limit indirection and make the code more readable, the above could moved to a function of sdfGeometryData and have here:
_sdfGeometryData.add(materialId, geom, neighbourIndices);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I renamed the variable to _sdf. Do you think it is readable enough then?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm sure, although my point was not exactly about the variable name. What I was trying to say is more that since those lines of code operate exclusively on the struct members, it could make sense to put them a member function of the struct which is called it from here... but that's fine as well.


std::vector<std::vector<size_t>> neighbours;
std::vector<size_t> neighboursFlat;
bool isDirty{false};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the dirty flag for other types of data is kept separately, maybe do the same for consistency..?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants